From cfcbe916129c3c1f24c2f309ca40a7c716ab55fa Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 7 Mar 2023 15:21:23 -0800 Subject: [PATCH 01/25] QueryBuilders --- src/sentry/search/events/builder/discover.py | 6 ++++++ src/sentry/search/events/builder/metrics.py | 7 +++++++ src/sentry/search/events/builder/sessions.py | 3 +++ 3 files changed, 16 insertions(+) diff --git a/src/sentry/search/events/builder/discover.py b/src/sentry/search/events/builder/discover.py index 5155fc8f3f8b73..378e047d996fe6 100644 --- a/src/sentry/search/events/builder/discover.py +++ b/src/sentry/search/events/builder/discover.py @@ -1440,6 +1440,9 @@ def get_snql_query(self) -> Request: limitby=self.limitby, ), flags=Flags(turbo=self.turbo), + tenant_ids={"organization_id": self.params.organization.id} + if self.params.organization + else None, ) @classmethod @@ -1611,6 +1614,9 @@ def get_snql_query(self) -> Request: granularity=self.granularity, limit=self.limit, ), + tenant_ids={"organization_id": self.params.organization.id} + if self.params.organization + else None, ) def run_query(self, referrer: str, use_cache: bool = False) -> Any: diff --git a/src/sentry/search/events/builder/metrics.py b/src/sentry/search/events/builder/metrics.py index 5abac7fbf5fd79..6ef06edf4ad1bc 100644 --- a/src/sentry/search/events/builder/metrics.py +++ b/src/sentry/search/events/builder/metrics.py @@ -460,6 +460,7 @@ def get_metrics_layer_snql_query(self) -> Request: granularity=self.granularity, ), flags=Flags(turbo=self.turbo), + tenant_ids={"organization_id": self.organization_id}, ) def get_snql_query(self) -> Request: @@ -511,6 +512,7 @@ def get_snql_query(self) -> Request: granularity=self.granularity, ), flags=Flags(turbo=self.turbo), + tenant_ids={"organization_id": self.organization_id}, ) def _create_query_framework(self) -> Tuple[str, Dict[str, QueryFramework]]: @@ -955,6 +957,9 @@ def get_snql_query(self) -> List[Request]: This is because different functions will use different entities """ + + tenant_ids = {"organization_id": self.organization_id} + # No need for primary from the query framework since there's no orderby to worry about if self.use_metrics_layer: prefix = "generic_" if self.dataset is Dataset.PerformanceMetrics else "" @@ -980,6 +985,7 @@ def get_snql_query(self) -> List[Request]: orderby=[], granularity=self.granularity, ), + tenant_ids=tenant_ids, ) ] _, query_framework = self._create_query_framework() @@ -1001,6 +1007,7 @@ def get_snql_query(self) -> List[Request]: granularity=self.granularity, limit=self.limit, ), + tenant_ids=tenant_ids, ) ) diff --git a/src/sentry/search/events/builder/sessions.py b/src/sentry/search/events/builder/sessions.py index b218b3638dd3fd..4e2d9e09dcb2b8 100644 --- a/src/sentry/search/events/builder/sessions.py +++ b/src/sentry/search/events/builder/sessions.py @@ -72,4 +72,7 @@ def get_snql_query(self) -> Request: limitby=self.limitby, ), flags=Flags(turbo=self.turbo), + tenant_ids={"organization_id": self.params.organization.id} + if self.params.organization + else None, ) From f58a0a2000a8b97e1ae503c681737c476bcc7338 Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 7 Mar 2023 15:33:50 -0800 Subject: [PATCH 02/25] get_series --- src/sentry/search/events/builder/metrics.py | 3 +++ src/sentry/snuba/metrics/datasource.py | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sentry/search/events/builder/metrics.py b/src/sentry/search/events/builder/metrics.py index 6ef06edf4ad1bc..50402ed32b0468 100644 --- a/src/sentry/search/events/builder/metrics.py +++ b/src/sentry/search/events/builder/metrics.py @@ -732,6 +732,9 @@ def run_query(self, referrer: str, use_cache: bool = False) -> Any: app_id="default", query=query, flags=Flags(turbo=self.turbo), + tenant_ids={"organization_id": self.params.organization.id} + if self.params.organization + else None, ) current_result = raw_snql_query( request, diff --git a/src/sentry/snuba/metrics/datasource.py b/src/sentry/snuba/metrics/datasource.py index e83afbe38ddbba..b512d39166902c 100644 --- a/src/sentry/snuba/metrics/datasource.py +++ b/src/sentry/snuba/metrics/datasource.py @@ -674,6 +674,8 @@ def get_series( ) -> dict: """Get time series for the given query""" + organization_id = projects[0].organization_id if projects else None + if metrics_query.interval is not None: interval = metrics_query.interval else: @@ -767,7 +769,10 @@ def get_series( initial_snuba_query = next(iter(snuba_queries.values()))["totals"] request = Request( - dataset=Dataset.Metrics.value, app_id="default", query=initial_snuba_query + dataset=Dataset.Metrics.value, + app_id="default", + query=initial_snuba_query, + tenant_ids={"organization_id": organization_id} if organization_id else None, ) initial_query_results = raw_snql_query( request, use_cache=False, referrer="api.metrics.totals.initial_query" From d87ca86ecb19911cfb1aa9d5162844a11f39a9ed Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 7 Mar 2023 15:53:51 -0800 Subject: [PATCH 03/25] refactor --- src/sentry/search/events/builder/discover.py | 14 ++++++++------ src/sentry/search/events/builder/metrics.py | 14 +++++--------- src/sentry/search/events/builder/sessions.py | 4 +--- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/sentry/search/events/builder/discover.py b/src/sentry/search/events/builder/discover.py index 378e047d996fe6..5c7bf81c3e8104 100644 --- a/src/sentry/search/events/builder/discover.py +++ b/src/sentry/search/events/builder/discover.py @@ -207,6 +207,12 @@ def __init__( "columns": set(), } + # Base Tenant IDs for any Snuba Request built/executed using a QueryBuilder + org_id = self.organization_id or ( + self.params.organization.id if self.params.organization else None + ) + self.tenant_ids = {"organization_id": org_id} if org_id else None + # Function is a subclass of CurriedFunction self.where: List[WhereType] = [] self.having: List[WhereType] = [] @@ -1440,9 +1446,7 @@ def get_snql_query(self) -> Request: limitby=self.limitby, ), flags=Flags(turbo=self.turbo), - tenant_ids={"organization_id": self.params.organization.id} - if self.params.organization - else None, + tenant_ids=self.tenant_ids, ) @classmethod @@ -1614,9 +1618,7 @@ def get_snql_query(self) -> Request: granularity=self.granularity, limit=self.limit, ), - tenant_ids={"organization_id": self.params.organization.id} - if self.params.organization - else None, + tenant_ids=self.tenant_ids, ) def run_query(self, referrer: str, use_cache: bool = False) -> Any: diff --git a/src/sentry/search/events/builder/metrics.py b/src/sentry/search/events/builder/metrics.py index 50402ed32b0468..53cbe293065fde 100644 --- a/src/sentry/search/events/builder/metrics.py +++ b/src/sentry/search/events/builder/metrics.py @@ -460,7 +460,7 @@ def get_metrics_layer_snql_query(self) -> Request: granularity=self.granularity, ), flags=Flags(turbo=self.turbo), - tenant_ids={"organization_id": self.organization_id}, + tenant_ids=self.tenant_ids, ) def get_snql_query(self) -> Request: @@ -512,7 +512,7 @@ def get_snql_query(self) -> Request: granularity=self.granularity, ), flags=Flags(turbo=self.turbo), - tenant_ids={"organization_id": self.organization_id}, + tenant_ids=self.tenant_ids, ) def _create_query_framework(self) -> Tuple[str, Dict[str, QueryFramework]]: @@ -732,9 +732,7 @@ def run_query(self, referrer: str, use_cache: bool = False) -> Any: app_id="default", query=query, flags=Flags(turbo=self.turbo), - tenant_ids={"organization_id": self.params.organization.id} - if self.params.organization - else None, + tenant_ids=self.tenant_ids, ) current_result = raw_snql_query( request, @@ -961,8 +959,6 @@ def get_snql_query(self) -> List[Request]: This is because different functions will use different entities """ - tenant_ids = {"organization_id": self.organization_id} - # No need for primary from the query framework since there's no orderby to worry about if self.use_metrics_layer: prefix = "generic_" if self.dataset is Dataset.PerformanceMetrics else "" @@ -988,7 +984,7 @@ def get_snql_query(self) -> List[Request]: orderby=[], granularity=self.granularity, ), - tenant_ids=tenant_ids, + tenant_ids=self.tenant_ids, ) ] _, query_framework = self._create_query_framework() @@ -1010,7 +1006,7 @@ def get_snql_query(self) -> List[Request]: granularity=self.granularity, limit=self.limit, ), - tenant_ids=tenant_ids, + tenant_ids=self.tenant_ids, ) ) diff --git a/src/sentry/search/events/builder/sessions.py b/src/sentry/search/events/builder/sessions.py index 4e2d9e09dcb2b8..b6aef681d15e38 100644 --- a/src/sentry/search/events/builder/sessions.py +++ b/src/sentry/search/events/builder/sessions.py @@ -72,7 +72,5 @@ def get_snql_query(self) -> Request: limitby=self.limitby, ), flags=Flags(turbo=self.turbo), - tenant_ids={"organization_id": self.params.organization.id} - if self.params.organization - else None, + tenant_ids=self.tenant_ids, ) From 92110d4e6cbd28bf6ec209eaf3c1f6276b8bec2d Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 7 Mar 2023 16:02:34 -0800 Subject: [PATCH 04/25] get_series --- src/sentry/api/endpoints/organization_metrics.py | 1 + src/sentry/release_health/metrics_sessions_v2.py | 7 ++++++- src/sentry/search/events/builder/metrics.py | 2 ++ src/sentry/snuba/metrics/datasource.py | 16 +++++++++++++--- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/sentry/api/endpoints/organization_metrics.py b/src/sentry/api/endpoints/organization_metrics.py index d3dca6e817ae8e..059a51b07bafee 100644 --- a/src/sentry/api/endpoints/organization_metrics.py +++ b/src/sentry/api/endpoints/organization_metrics.py @@ -164,6 +164,7 @@ def data_fn(offset: int, limit: int): projects, query.to_metrics_query(), use_case_id=get_use_case_id(request.GET.get("useCase", "release-health")), + tenant_ids={"organization_id": organization.id}, ) data["query"] = query.query except ( diff --git a/src/sentry/release_health/metrics_sessions_v2.py b/src/sentry/release_health/metrics_sessions_v2.py index e2bcc5afc0a813..ded129612bb6e5 100644 --- a/src/sentry/release_health/metrics_sessions_v2.py +++ b/src/sentry/release_health/metrics_sessions_v2.py @@ -567,7 +567,12 @@ def run_sessions_query( # TODO: Stop passing project IDs everywhere projects = Project.objects.get_many_from_cache(project_ids) try: - metrics_results = get_series(projects, metrics_query, use_case_id=UseCaseKey.RELEASE_HEALTH) + metrics_results = get_series( + projects, + metrics_query, + use_case_id=UseCaseKey.RELEASE_HEALTH, + tenant_ids={"organization_id": org_id}, + ) except OrderByNotSupportedOverCompositeEntityException: raise InvalidParams(f"Cannot order by {query.raw_orderby[0]} with the current filters") except UtilsInvalidParams as e: diff --git a/src/sentry/search/events/builder/metrics.py b/src/sentry/search/events/builder/metrics.py index 53cbe293065fde..03a11942424ce8 100644 --- a/src/sentry/search/events/builder/metrics.py +++ b/src/sentry/search/events/builder/metrics.py @@ -636,6 +636,7 @@ def run_query(self, referrer: str, use_cache: bool = False) -> Any: if self.is_performance else UseCaseKey.RELEASE_HEALTH, include_meta=True, + tenant_ids=self.tenant_ids, ) except Exception as err: raise IncompatibleMetricsQuery(err) @@ -1033,6 +1034,7 @@ def run_query(self, referrer: str, use_cache: bool = False) -> Any: if self.is_performance else UseCaseKey.RELEASE_HEALTH, include_meta=True, + tenant_ids=self.tenant_ids, ) except Exception as err: raise IncompatibleMetricsQuery(err) diff --git a/src/sentry/snuba/metrics/datasource.py b/src/sentry/snuba/metrics/datasource.py index b512d39166902c..d53862782fb502 100644 --- a/src/sentry/snuba/metrics/datasource.py +++ b/src/sentry/snuba/metrics/datasource.py @@ -1,3 +1,5 @@ +from __future__ import annotations + """ Module that gets both metadata and time series from Snuba. For metadata, it fetch metrics metadata (metric names, tag names, tag values, ...) from snuba. @@ -671,10 +673,12 @@ def get_series( metrics_query: MetricsQuery, use_case_id: UseCaseKey, include_meta: bool = False, + tenant_ids: dict[str, Any] | None = None, ) -> dict: """Get time series for the given query""" organization_id = projects[0].organization_id if projects else None + tenant_ids = tenant_ids or {"organization_id": organization_id} if organization_id else None if metrics_query.interval is not None: interval = metrics_query.interval @@ -772,7 +776,7 @@ def get_series( dataset=Dataset.Metrics.value, app_id="default", query=initial_snuba_query, - tenant_ids={"organization_id": organization_id} if organization_id else None, + tenant_ids=tenant_ids, ) initial_query_results = raw_snql_query( request, use_cache=False, referrer="api.metrics.totals.initial_query" @@ -811,7 +815,10 @@ def get_series( snuba_query = _apply_group_limit_filters(snuba_query, group_limit_filters) request = Request( - dataset=Dataset.Metrics.value, app_id="default", query=snuba_query + dataset=Dataset.Metrics.value, + app_id="default", + query=snuba_query, + tenant_ids=tenant_ids, ) snuba_result = raw_snql_query( request, use_cache=False, referrer=f"api.metrics.{key}.second_query" @@ -840,7 +847,10 @@ def get_series( snuba_query = _apply_group_limit_filters(snuba_query, group_limit_filters) request = Request( - dataset=Dataset.Metrics.value, app_id="default", query=snuba_query + dataset=Dataset.Metrics.value, + app_id="default", + query=snuba_query, + tenant_ids=tenant_ids, ) snuba_result = raw_snql_query( request, From 4226518e6ee693b9a7c0e9c270d033a8aafc71e1 Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 7 Mar 2023 16:06:25 -0800 Subject: [PATCH 05/25] outcomes_query_timeseries --- src/sentry/api/endpoints/organization_stats_v2.py | 4 +++- src/sentry/api/endpoints/project_key_stats.py | 6 +++++- src/sentry/snuba/outcomes.py | 6 ++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/sentry/api/endpoints/organization_stats_v2.py b/src/sentry/api/endpoints/organization_stats_v2.py index 977751d7efad98..44769337ea4ac8 100644 --- a/src/sentry/api/endpoints/organization_stats_v2.py +++ b/src/sentry/api/endpoints/organization_stats_v2.py @@ -183,7 +183,9 @@ def get(self, request: Request, organization) -> Response: result_timeseries = ( None if "project_id" in query.query_groupby - else run_outcomes_query_timeseries(query) + else run_outcomes_query_timeseries( + query, tenant_ids={"organization_id": organization.id} + ) ) with sentry_sdk.start_span( op="outcomes.endpoint", description="massage_outcomes_result" diff --git a/src/sentry/api/endpoints/project_key_stats.py b/src/sentry/api/endpoints/project_key_stats.py index 6decee7b2dbeb9..bc99c4946658f8 100644 --- a/src/sentry/api/endpoints/project_key_stats.py +++ b/src/sentry/api/endpoints/project_key_stats.py @@ -68,7 +68,11 @@ def get(self, request: Request, project, key_id) -> Response: {"organization_id": project.organization_id}, ) results = massage_outcomes_result( - query_definition, [], run_outcomes_query_timeseries(query_definition) + query_definition, + [], + run_outcomes_query_timeseries( + query_definition, tenant_ids={"organization_id": project.organization_id} + ), ) except Exception: raise ParseError(detail="Invalid request data") diff --git a/src/sentry/snuba/outcomes.py b/src/sentry/snuba/outcomes.py index 16ef503225714e..0a02935e099b30 100644 --- a/src/sentry/snuba/outcomes.py +++ b/src/sentry/snuba/outcomes.py @@ -313,7 +313,7 @@ def run_outcomes_query_totals(query: QueryDefinition) -> ResultSet: return _format_rows(result["data"], query) -def run_outcomes_query_timeseries(query: QueryDefinition) -> ResultSet: +def run_outcomes_query_timeseries(query: QueryDefinition, tenant_ids=None) -> ResultSet: snql_query = Query( match=Entity(query.match), select=query.select_params, @@ -324,7 +324,9 @@ def run_outcomes_query_timeseries(query: QueryDefinition) -> ResultSet: granularity=Granularity(query.rollup), ) request = Request(dataset=query.dataset.value, app_id="default", query=snql_query) - result_timeseries = raw_snql_query(request, referrer="outcomes.timeseries") + result_timeseries = raw_snql_query( + request, referrer="outcomes.timeseries", tenant_ids=tenant_ids + ) return _format_rows(result_timeseries["data"], query) From 786dbe8c8bcf8a05f5bcda8097c244c188de43f6 Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 7 Mar 2023 16:10:59 -0800 Subject: [PATCH 06/25] mypy --- src/sentry/snuba/outcomes.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sentry/snuba/outcomes.py b/src/sentry/snuba/outcomes.py index 0a02935e099b30..a6c4d218ecbcdf 100644 --- a/src/sentry/snuba/outcomes.py +++ b/src/sentry/snuba/outcomes.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from abc import ABC, abstractmethod from typing import Any, Dict, List, Mapping, MutableMapping, Optional, Sequence, Tuple @@ -313,7 +315,9 @@ def run_outcomes_query_totals(query: QueryDefinition) -> ResultSet: return _format_rows(result["data"], query) -def run_outcomes_query_timeseries(query: QueryDefinition, tenant_ids=None) -> ResultSet: +def run_outcomes_query_timeseries( + query: QueryDefinition, tenant_ids: dict[str, Any] | None = None +) -> ResultSet: snql_query = Query( match=Entity(query.match), select=query.select_params, From 7a4e825db8fc016b6284564edd96be43f1fd102e Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 7 Mar 2023 16:20:53 -0800 Subject: [PATCH 07/25] outcomes.totals --- src/sentry/api/endpoints/organization_stats_v2.py | 7 +++---- src/sentry/snuba/outcomes.py | 14 +++++++++----- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/sentry/api/endpoints/organization_stats_v2.py b/src/sentry/api/endpoints/organization_stats_v2.py index 44769337ea4ac8..754de447ccd657 100644 --- a/src/sentry/api/endpoints/organization_stats_v2.py +++ b/src/sentry/api/endpoints/organization_stats_v2.py @@ -173,19 +173,18 @@ def get(self, request: Request, organization) -> Response: Select a field, define a date range, and group or filter by columns. """ with self.handle_query_errors(): + tenant_ids = {"organization_id": organization.id} with sentry_sdk.start_span(op="outcomes.endpoint", description="build_outcomes_query"): query = self.build_outcomes_query( request, organization, ) with sentry_sdk.start_span(op="outcomes.endpoint", description="run_outcomes_query"): - result_totals = run_outcomes_query_totals(query) + result_totals = run_outcomes_query_totals(query, tenant_ids=tenant_ids) result_timeseries = ( None if "project_id" in query.query_groupby - else run_outcomes_query_timeseries( - query, tenant_ids={"organization_id": organization.id} - ) + else run_outcomes_query_timeseries(query, tenant_ids=tenant_ids) ) with sentry_sdk.start_span( op="outcomes.endpoint", description="massage_outcomes_result" diff --git a/src/sentry/snuba/outcomes.py b/src/sentry/snuba/outcomes.py index a6c4d218ecbcdf..6cece3bcbeb33f 100644 --- a/src/sentry/snuba/outcomes.py +++ b/src/sentry/snuba/outcomes.py @@ -300,7 +300,9 @@ def get_conditions(self, query: QueryDict, params: Mapping[Any, Any]) -> List[An return query_conditions -def run_outcomes_query_totals(query: QueryDefinition) -> ResultSet: +def run_outcomes_query_totals( + query: QueryDefinition, tenant_ids: dict[str, Any] | None = None +) -> ResultSet: snql_query = Query( match=Entity(query.match), select=query.select_params, @@ -310,7 +312,9 @@ def run_outcomes_query_totals(query: QueryDefinition) -> ResultSet: offset=Offset(0), granularity=Granularity(query.rollup), ) - request = Request(dataset=query.dataset.value, app_id="default", query=snql_query) + request = Request( + dataset=query.dataset.value, app_id="default", query=snql_query, tenant_ids=tenant_ids + ) result = raw_snql_query(request, referrer="outcomes.totals") return _format_rows(result["data"], query) @@ -327,10 +331,10 @@ def run_outcomes_query_timeseries( offset=Offset(0), granularity=Granularity(query.rollup), ) - request = Request(dataset=query.dataset.value, app_id="default", query=snql_query) - result_timeseries = raw_snql_query( - request, referrer="outcomes.timeseries", tenant_ids=tenant_ids + request = Request( + dataset=query.dataset.value, app_id="default", query=snql_query, tenant_ids=tenant_ids ) + result_timeseries = raw_snql_query(request, referrer="outcomes.timeseries") return _format_rows(result_timeseries["data"], query) From 49dca4862fe2ccc79e2b18f6befac7a1ec39a99c Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Wed, 8 Mar 2023 14:33:14 -0800 Subject: [PATCH 08/25] snuba_search --- src/sentry/search/snuba/executors.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sentry/search/snuba/executors.py b/src/sentry/search/snuba/executors.py index 36ecf2dc1c3e18..e777c85fa3f264 100644 --- a/src/sentry/search/snuba/executors.py +++ b/src/sentry/search/snuba/executors.py @@ -278,7 +278,7 @@ def _prepare_params_for_category( ) strategy = SEARCH_STRATEGIES.get(group_category, _query_params_for_generic) - return strategy( + snuba_query_params = strategy( pinned_query_partial, selected_columns, aggregations, @@ -290,6 +290,8 @@ def _prepare_params_for_category( conditions, actor, ) + snuba_query_params.kwargs["tenant_ids"] = {"organization_id": organization_id} + return snuba_query_params def snuba_search( self, From 7dd5c697e7c699c0fc2873b64f7776eced6bd0ca Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Wed, 8 Mar 2023 14:35:39 -0800 Subject: [PATCH 09/25] cdc --- src/sentry/search/snuba/executors.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/sentry/search/snuba/executors.py b/src/sentry/search/snuba/executors.py index e777c85fa3f264..8afb8215a43639 100644 --- a/src/sentry/search/snuba/executors.py +++ b/src/sentry/search/snuba/executors.py @@ -1007,6 +1007,8 @@ def query( op = Op.GTE if cursor.is_prev else Op.LTE having.append(Condition(sort_func, op, cursor.value)) + tenant_ids = {"organization_id": projects[0].organization_id} if projects else None + query = Query( match=Join([Relationship(e_event, "grouped", e_group)]), select=[ @@ -1019,7 +1021,12 @@ def query( orderby=[OrderBy(sort_func, direction=Direction.DESC)], limit=Limit(limit + 1), ) - request = Request(dataset="events", app_id="cdc", query=query) + request = Request( + dataset="events", + app_id="cdc", + query=query, + tenant_ids=tenant_ids, + ) data = snuba.raw_snql_query(request, referrer="search.snuba.cdc_search.query")["data"] hits_query = Query( @@ -1031,7 +1038,9 @@ def query( ) hits = None if count_hits: - request = Request(dataset="events", app_id="cdc", query=hits_query) + request = Request( + dataset="events", app_id="cdc", query=hits_query, tenant_ids=tenant_ids + ) hits = snuba.raw_snql_query(request, referrer="search.snuba.cdc_search.hits")["data"][ 0 ]["count"] From e9e3f6b8627586e6b7e9cdbaa7a5b0620fc95ce9 Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Wed, 8 Mar 2023 14:49:28 -0800 Subject: [PATCH 10/25] group serializer --- src/sentry/api/serializers/models/group.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/sentry/api/serializers/models/group.py b/src/sentry/api/serializers/models/group.py index 9f00c5d44f55ff..5dd114edf9be8f 100644 --- a/src/sentry/api/serializers/models/group.py +++ b/src/sentry/api/serializers/models/group.py @@ -532,6 +532,9 @@ def _get_group_snuba_stats( start=start, orderby="group_id", referrer="group.unhandled-flag", + tenant_ids={"organization_id": item_list[0].project.organization_id} + if item_list + else None, ) for x in rv["data"]: unhandled[x["group_id"]] = x["unhandled"] @@ -1017,9 +1020,6 @@ def _execute_error_seen_stats_query( if environment_ids: filters["environment"] = environment_ids - org_id = item_list[0].project.organization_id if item_list else None - tenant_ids = {"organization_id": org_id} if org_id else dict() - return aliased_query( dataset=Dataset.Events, start=start, @@ -1029,7 +1029,9 @@ def _execute_error_seen_stats_query( filter_keys=filters, aggregations=aggregations, referrer="serializers.GroupSerializerSnuba._execute_error_seen_stats_query", - tenant_ids=tenant_ids, + tenant_ids={"organization_id": item_list[0].project.organization_id} + if item_list + else None, ) @staticmethod @@ -1060,6 +1062,9 @@ def _execute_perf_seen_stats_query( filter_keys=filters, aggregations=aggregations, referrer="serializers.GroupSerializerSnuba._execute_perf_seen_stats_query", + tenant_ids={"organization_id": item_list[0].project.organization_id} + if item_list + else None, ) @staticmethod @@ -1086,6 +1091,9 @@ def _execute_generic_seen_stats_query( filter_keys=filters, aggregations=aggregations, referrer="serializers.GroupSerializerSnuba._execute_generic_seen_stats_query", + tenant_ids={"organization_id": item_list[0].project.organization_id} + if item_list + else None, ) @staticmethod From 978eaa73d66b537659fbe5702123f66d655206b6 Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Wed, 8 Mar 2023 14:52:18 -0800 Subject: [PATCH 11/25] typing --- src/sentry/search/snuba/executors.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sentry/search/snuba/executors.py b/src/sentry/search/snuba/executors.py index 8afb8215a43639..85b19dd80aed0d 100644 --- a/src/sentry/search/snuba/executors.py +++ b/src/sentry/search/snuba/executors.py @@ -290,7 +290,8 @@ def _prepare_params_for_category( conditions, actor, ) - snuba_query_params.kwargs["tenant_ids"] = {"organization_id": organization_id} + if snuba_query_params is not None: + snuba_query_params.kwargs["tenant_ids"] = {"organization_id": organization_id} return snuba_query_params def snuba_search( From 0d13cea126a46cd9fe46557fc4ea5401a78a6e2f Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Wed, 8 Mar 2023 16:05:16 -0800 Subject: [PATCH 12/25] easy get_events() --- src/sentry/api/endpoints/organization_eventid.py | 4 +++- src/sentry/eventstore/base.py | 1 + src/sentry/eventstore/snuba/backend.py | 5 +++++ src/sentry/models/group.py | 1 + src/sentry/testutils/relay.py | 10 ++++++++-- 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/sentry/api/endpoints/organization_eventid.py b/src/sentry/api/endpoints/organization_eventid.py index e45f94489f9642..9d4a1c5edf8cfe 100644 --- a/src/sentry/api/endpoints/organization_eventid.py +++ b/src/sentry/api/endpoints/organization_eventid.py @@ -48,7 +48,9 @@ def get(self, request: Request, organization, event_id) -> Response: project_ids=list(project_slugs_by_id.keys()), event_ids=[event_id], ) - event = eventstore.get_events(filter=snuba_filter, limit=1)[0] + event = eventstore.get_events( + filter=snuba_filter, limit=1, tenant_ids={"organization_id": organization.id} + )[0] except IndexError: raise ResourceDoesNotExist() else: diff --git a/src/sentry/eventstore/base.py b/src/sentry/eventstore/base.py index a5e408169ad079..e8f6f8c0d5f59f 100644 --- a/src/sentry/eventstore/base.py +++ b/src/sentry/eventstore/base.py @@ -156,6 +156,7 @@ def get_events( limit=100, offset=0, referrer="eventstore.get_events", + tenant_ids=None, ): """ Fetches a list of events given a set of criteria. diff --git a/src/sentry/eventstore/snuba/backend.py b/src/sentry/eventstore/snuba/backend.py index 6eea56db34bb7e..cafb179d5f5544 100644 --- a/src/sentry/eventstore/snuba/backend.py +++ b/src/sentry/eventstore/snuba/backend.py @@ -55,6 +55,7 @@ def get_events( offset=DEFAULT_OFFSET, referrer="eventstore.get_events", dataset=snuba.Dataset.Events, + tenant_ids=None, ): """ Get events from Snuba, with node data loaded. @@ -68,6 +69,7 @@ def get_events( referrer=referrer, should_bind_nodes=True, dataset=dataset, + tenant_ids=tenant_ids, ) def get_unfetched_events( @@ -101,6 +103,7 @@ def __get_events( referrer=None, should_bind_nodes=False, dataset=snuba.Dataset.Events, + tenant_ids=None, ): assert filter, "You must provide a filter" cols = self.__get_columns(dataset) @@ -142,6 +145,7 @@ def __get_events( offset=DEFAULT_OFFSET, referrer=referrer, dataset=dataset, + tenant_ids=tenant_ids, ) if "error" not in result: @@ -169,6 +173,7 @@ def __get_events( offset=offset, referrer=referrer, dataset=dataset, + tenant_ids=tenant_ids, ) if "error" not in result: diff --git a/src/sentry/models/group.py b/src/sentry/models/group.py index 2025c02cd8dfb3..e89372c7b0787a 100644 --- a/src/sentry/models/group.py +++ b/src/sentry/models/group.py @@ -213,6 +213,7 @@ def get_oldest_or_latest_event_for_environments( orderby=ordering.value, referrer="Group.get_latest", dataset=dataset, + tenant_ids={"organization_id": group.project.organization_id}, ) if events: diff --git a/src/sentry/testutils/relay.py b/src/sentry/testutils/relay.py index 3a96216cd2f139..6baff7102183be 100644 --- a/src/sentry/testutils/relay.py +++ b/src/sentry/testutils/relay.py @@ -71,14 +71,20 @@ def post_and_retrieve_security_report(self, data): url = self.get_relay_security_url(self.project.id, self.projectkey.public_key) responses.add_passthru(url) + tenant_ids = {"organization_id": self.project.organization_id} event_ids = { event.event_id - for event in eventstore.get_events(eventstore.Filter(project_ids=[self.project.id])) + for event in eventstore.get_events( + eventstore.Filter(project_ids=[self.project.id]), + tenant_ids=tenant_ids, + ) } def has_new_event(): # Hack: security report endpoint does not return event ID - for event in eventstore.get_events(eventstore.Filter(project_ids=[self.project.id])): + for event in eventstore.get_events( + eventstore.Filter(project_ids=[self.project.id]), tenant_ids=tenant_ids + ): if event.event_id not in event_ids: return event From 602e96103278c46ef7c5e6204d716945be925c98 Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Wed, 8 Mar 2023 16:07:45 -0800 Subject: [PATCH 13/25] filter_by_event_id --- src/sentry/api/endpoints/organization_group_index.py | 8 +++++++- src/sentry/models/group.py | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/sentry/api/endpoints/organization_group_index.py b/src/sentry/api/endpoints/organization_group_index.py index a91de0b8ee6885..2bb1e26fa7292e 100644 --- a/src/sentry/api/endpoints/organization_group_index.py +++ b/src/sentry/api/endpoints/organization_group_index.py @@ -280,7 +280,13 @@ def get(self, request: Request, organization) -> Response: direct_hit_projects = ( set(project_ids) | request.access.project_ids_with_team_membership ) - groups = list(Group.objects.filter_by_event_id(direct_hit_projects, event_id)) + groups = list( + Group.objects.filter_by_event_id( + direct_hit_projects, + event_id, + tenant_ids={"organization_id": organization.id}, + ) + ) if len(groups) == 1: serialized_groups = serialize(groups, request.user, serializer()) if event_id: diff --git a/src/sentry/models/group.py b/src/sentry/models/group.py index e89372c7b0787a..eedc48b944ce75 100644 --- a/src/sentry/models/group.py +++ b/src/sentry/models/group.py @@ -291,7 +291,7 @@ def from_event_id(self, project, event_id): return self.get(id=group_id) - def filter_by_event_id(self, project_ids, event_id): + def filter_by_event_id(self, project_ids, event_id, tenant_ids=None): events = eventstore.get_events( filter=eventstore.Filter( event_ids=[event_id], @@ -300,6 +300,7 @@ def filter_by_event_id(self, project_ids, event_id): ), limit=max(len(project_ids), 100), referrer="Group.filter_by_event_id", + tenant_ids=tenant_ids, ) return self.filter(id__in={event.group_id for event in events}) From 2bbf5270adb63fed3f19c98bec76376fce92fe00 Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Mon, 13 Mar 2023 11:04:25 -0700 Subject: [PATCH 14/25] tasks --- src/sentry/data_export/tasks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sentry/data_export/tasks.py b/src/sentry/data_export/tasks.py index 63033af6cef9c7..67afc58af87b83 100644 --- a/src/sentry/data_export/tasks.py +++ b/src/sentry/data_export/tasks.py @@ -216,6 +216,7 @@ def get_processor(data_export, environment_id): group_id=payload["group"], key=payload["key"], environment_id=environment_id, + tenant_ids={"organization_id": data_export.organization_id}, ) elif data_export.query_type == ExportQueryType.DISCOVER: processor = DiscoverProcessor( From 00f65248c19a194364eb53bea2213e200353f405 Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 14 Mar 2023 10:46:29 -0700 Subject: [PATCH 15/25] undo test util change --- src/sentry/testutils/relay.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/sentry/testutils/relay.py b/src/sentry/testutils/relay.py index 6baff7102183be..3a96216cd2f139 100644 --- a/src/sentry/testutils/relay.py +++ b/src/sentry/testutils/relay.py @@ -71,20 +71,14 @@ def post_and_retrieve_security_report(self, data): url = self.get_relay_security_url(self.project.id, self.projectkey.public_key) responses.add_passthru(url) - tenant_ids = {"organization_id": self.project.organization_id} event_ids = { event.event_id - for event in eventstore.get_events( - eventstore.Filter(project_ids=[self.project.id]), - tenant_ids=tenant_ids, - ) + for event in eventstore.get_events(eventstore.Filter(project_ids=[self.project.id])) } def has_new_event(): # Hack: security report endpoint does not return event ID - for event in eventstore.get_events( - eventstore.Filter(project_ids=[self.project.id]), tenant_ids=tenant_ids - ): + for event in eventstore.get_events(eventstore.Filter(project_ids=[self.project.id])): if event.event_id not in event_ids: return event From 78952ab15bc836d39b9301a8c7a3ae1594a15ad2 Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 14 Mar 2023 12:45:57 -0700 Subject: [PATCH 16/25] outcomes.timeseries referrer optional --- src/sentry/snuba/outcomes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sentry/snuba/outcomes.py b/src/sentry/snuba/outcomes.py index 6cece3bcbeb33f..e10fe9100fcad7 100644 --- a/src/sentry/snuba/outcomes.py +++ b/src/sentry/snuba/outcomes.py @@ -320,7 +320,7 @@ def run_outcomes_query_totals( def run_outcomes_query_timeseries( - query: QueryDefinition, tenant_ids: dict[str, Any] | None = None + query: QueryDefinition, tenant_ids: dict[str, Any] | None = None, referrer="outcomes.timeseries" ) -> ResultSet: snql_query = Query( match=Entity(query.match), @@ -334,7 +334,7 @@ def run_outcomes_query_timeseries( request = Request( dataset=query.dataset.value, app_id="default", query=snql_query, tenant_ids=tenant_ids ) - result_timeseries = raw_snql_query(request, referrer="outcomes.timeseries") + result_timeseries = raw_snql_query(request, referrer=referrer) return _format_rows(result_timeseries["data"], query) From 7343733fe41e5eb28482867d6c73343fc0d364e0 Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 14 Mar 2023 12:50:34 -0700 Subject: [PATCH 17/25] disclaimer for outcomes.timeseries --- src/sentry/snuba/outcomes.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sentry/snuba/outcomes.py b/src/sentry/snuba/outcomes.py index e10fe9100fcad7..e29ea532e7f365 100644 --- a/src/sentry/snuba/outcomes.py +++ b/src/sentry/snuba/outcomes.py @@ -322,6 +322,11 @@ def run_outcomes_query_totals( def run_outcomes_query_timeseries( query: QueryDefinition, tenant_ids: dict[str, Any] | None = None, referrer="outcomes.timeseries" ) -> ResultSet: + """ + Runs an outcomes query. By default the referrer is `outcomes.timeseries` and this should not change + unless there is a very specific reason to do so. Eg. getsentry uses this function for billing + metrics, so the referrer is different as it's no longer a "product" query. + """ snql_query = Query( match=Entity(query.match), select=query.select_params, From 7f987a389db610db1b87f958430a41f8ab47c0eb Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 14 Mar 2023 12:56:33 -0700 Subject: [PATCH 18/25] typing --- src/sentry/snuba/outcomes.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sentry/snuba/outcomes.py b/src/sentry/snuba/outcomes.py index e29ea532e7f365..5b434605499d48 100644 --- a/src/sentry/snuba/outcomes.py +++ b/src/sentry/snuba/outcomes.py @@ -320,7 +320,9 @@ def run_outcomes_query_totals( def run_outcomes_query_timeseries( - query: QueryDefinition, tenant_ids: dict[str, Any] | None = None, referrer="outcomes.timeseries" + query: QueryDefinition, + tenant_ids: dict[str, Any] | None = None, + referrer: str = "outcomes.timeseries", ) -> ResultSet: """ Runs an outcomes query. By default the referrer is `outcomes.timeseries` and this should not change From 0ad129840fc168d7ac7dcec998b75418b2bf3ad1 Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 14 Mar 2023 14:01:21 -0700 Subject: [PATCH 19/25] api.project-events --- src/sentry/api/endpoints/project_events.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sentry/api/endpoints/project_events.py b/src/sentry/api/endpoints/project_events.py index 86495713de5211..f64a772a104b40 100644 --- a/src/sentry/api/endpoints/project_events.py +++ b/src/sentry/api/endpoints/project_events.py @@ -60,6 +60,7 @@ def get(self, request: Request, project) -> Response: eventstore.get_events, filter=event_filter, referrer="api.project-events", + tenant_ids={"organization_id": project.organization_id}, ) serializer = EventSerializer() if full else SimpleEventSerializer() From 4dfa970c13b13dff2eaacc4b735a886c252d228d Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 14 Mar 2023 14:23:47 -0700 Subject: [PATCH 20/25] get_unfetched_events --- src/sentry/deletions/defaults/group.py | 3 +++ src/sentry/eventstore/base.py | 1 + src/sentry/eventstore/snuba/backend.py | 2 ++ src/sentry/tasks/reprocessing2.py | 3 ++- src/sentry/tasks/unmerge.py | 1 + src/sentry/utils/query.py | 10 +++++++++- 6 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/sentry/deletions/defaults/group.py b/src/sentry/deletions/defaults/group.py index 78fde8da37f3e9..2040287a672f79 100644 --- a/src/sentry/deletions/defaults/group.py +++ b/src/sentry/deletions/defaults/group.py @@ -80,6 +80,9 @@ def chunk(self): limit=self.DEFAULT_CHUNK_SIZE, referrer="deletions.group", orderby=["-timestamp", "-event_id"], + tenant_ids={"organization_id": self.groups[0].project.organization_id} + if self.groups + else None, ) if not events: # Remove all group events now that their node data has been removed. diff --git a/src/sentry/eventstore/base.py b/src/sentry/eventstore/base.py index e8f6f8c0d5f59f..960edeb2ff6ff3 100644 --- a/src/sentry/eventstore/base.py +++ b/src/sentry/eventstore/base.py @@ -180,6 +180,7 @@ def get_unfetched_events( limit=100, offset=0, referrer="eventstore.get_unfetched_events", + tenant_ids=None, ): """ Same as get_events but returns events without their node datas loaded. diff --git a/src/sentry/eventstore/snuba/backend.py b/src/sentry/eventstore/snuba/backend.py index cafb179d5f5544..af8b1662e8a9bb 100644 --- a/src/sentry/eventstore/snuba/backend.py +++ b/src/sentry/eventstore/snuba/backend.py @@ -80,6 +80,7 @@ def get_unfetched_events( offset=DEFAULT_OFFSET, referrer="eventstore.get_unfetched_events", dataset=snuba.Dataset.Events, + tenant_ids=None, ): """ Get events from Snuba, without node data loaded. @@ -92,6 +93,7 @@ def get_unfetched_events( referrer=referrer, should_bind_nodes=False, dataset=dataset, + tenant_ids=tenant_ids, ) def __get_events( diff --git a/src/sentry/tasks/reprocessing2.py b/src/sentry/tasks/reprocessing2.py index 399f7a7bf65893..fe114a02e60712 100644 --- a/src/sentry/tasks/reprocessing2.py +++ b/src/sentry/tasks/reprocessing2.py @@ -4,7 +4,7 @@ from django.conf import settings from django.db import transaction -from sentry import eventstore, eventstream, nodestore +from sentry import eventstore, eventstream, models, nodestore from sentry.eventstore.models import Event from sentry.reprocessing2 import buffered_delete_old_primary_hash from sentry.tasks.base import instrumented_task, retry @@ -64,6 +64,7 @@ def reprocess_group( batch_size=settings.SENTRY_REPROCESSING_PAGE_SIZE, state=query_state, referrer="reprocessing2.reprocess_group", + tenant_ids={"organization_id": models.Project.objects.get(id=project_id).organization_id}, ) if not events: diff --git a/src/sentry/tasks/unmerge.py b/src/sentry/tasks/unmerge.py index 2ca5b7088404cf..84c8b90a42b2e8 100644 --- a/src/sentry/tasks/unmerge.py +++ b/src/sentry/tasks/unmerge.py @@ -489,6 +489,7 @@ def unmerge(*posargs, **kwargs): batch_size=args.batch_size, state=last_event, referrer="unmerge", + tenant_ids={"organization_id": source.project.organization_id}, ) # If there are no more events to process, we're done with the migration. diff --git a/src/sentry/utils/query.py b/src/sentry/utils/query.py index a8df5c69af7860..aa0cad3c61b7c8 100644 --- a/src/sentry/utils/query.py +++ b/src/sentry/utils/query.py @@ -12,7 +12,14 @@ class InvalidQuerySetError(ValueError): pass -def celery_run_batch_query(filter, batch_size, referrer, state=None, fetch_events=True): +def celery_run_batch_query( + filter, + batch_size, + referrer, + state=None, + fetch_events=True, + tenant_ids=None, +): """ A tool for batched queries similar in purpose to RangeQuerySetWrapper that is used for celery tasks in issue merge/unmerge/reprocessing. @@ -50,6 +57,7 @@ def celery_run_batch_query(filter, batch_size, referrer, state=None, fetch_event limit=batch_size, referrer=referrer, orderby=["-timestamp", "-event_id"], + tenant_ids=tenant_ids, ) ) From 13f410aafac04cbb5e40deed10ad1a637391a435 Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 14 Mar 2023 14:33:32 -0700 Subject: [PATCH 21/25] get next/prev event --- src/sentry/eventstore/snuba/backend.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/sentry/eventstore/snuba/backend.py b/src/sentry/eventstore/snuba/backend.py index af8b1662e8a9bb..5034e5adde7130 100644 --- a/src/sentry/eventstore/snuba/backend.py +++ b/src/sentry/eventstore/snuba/backend.py @@ -286,7 +286,12 @@ def get_next_event_id(self, event, filter): filter.conditions.extend(get_after_event_condition(event)) filter.start = event.datetime dataset = self._get_dataset_for_event(event) - return self.__get_event_id_from_filter(filter=filter, orderby=ASC_ORDERING, dataset=dataset) + return self.__get_event_id_from_filter( + filter=filter, + orderby=ASC_ORDERING, + dataset=dataset, + tenant_ids={"organization_id": event.project.organization_id}, + ) def get_prev_event_id(self, event, filter): """ @@ -306,13 +311,18 @@ def get_prev_event_id(self, event, filter): filter.end = event.datetime + timedelta(seconds=1) dataset = self._get_dataset_for_event(event) return self.__get_event_id_from_filter( - filter=filter, orderby=DESC_ORDERING, dataset=dataset + filter=filter, + orderby=DESC_ORDERING, + dataset=dataset, + tenant_ids={"organization_id": event.project.organization_id}, ) def __get_columns(self, dataset: Dataset): return [col.value.event_name for col in EventStorage.minimal_columns[dataset]] - def __get_event_id_from_filter(self, filter=None, orderby=None, dataset=snuba.Dataset.Discover): + def __get_event_id_from_filter( + self, filter=None, orderby=None, dataset=snuba.Dataset.Discover, tenant_ids=None + ): columns = [Columns.EVENT_ID.value.alias, Columns.PROJECT_ID.value.alias] try: # This query uses the discover dataset to enable From edf1ee68f03f3259c44f164bc18272bba4b10d79 Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 14 Mar 2023 14:39:18 -0700 Subject: [PATCH 22/25] preview.get_events --- src/sentry/api/endpoints/group_hashes.py | 1 + src/sentry/rules/history/preview.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sentry/api/endpoints/group_hashes.py b/src/sentry/api/endpoints/group_hashes.py index a4a52cb28c59f8..40032e734c3236 100644 --- a/src/sentry/api/endpoints/group_hashes.py +++ b/src/sentry/api/endpoints/group_hashes.py @@ -37,6 +37,7 @@ def get(self, request: Request, group) -> Response: groupby=["primary_hash"], referrer="api.group-hashes", orderby=["-latest_event_timestamp"], + tenant_ids={"organization_id": group.project.organization_id}, ) handle_results = partial(self.__handle_results, group.project_id, group.id, request.user) diff --git a/src/sentry/rules/history/preview.py b/src/sentry/rules/history/preview.py index 617fb6aca7996b..f27ed7c6b2442b 100644 --- a/src/sentry/rules/history/preview.py +++ b/src/sentry/rules/history/preview.py @@ -313,6 +313,7 @@ def get_events( events = [] query_params = [] + tenant_ids = {"organization_id": project.organization_id} # query events by group_id (first event for each group) for dataset, ids in group_ids.items(): if dataset not in columns or dataset == Dataset.Transactions: @@ -332,7 +333,7 @@ def get_events( "selected_columns": columns[dataset] + ["group_id"], }, ) - query_params.append(SnubaQueryParams(**kwargs)) + query_params.append(SnubaQueryParams(**kwargs, tenant_ids=tenant_ids)) # query events by event_id for dataset, ids in event_ids.items(): @@ -346,6 +347,7 @@ def get_events( filter_keys={"project_id": [project.id]}, conditions=[("event_id", "IN", ids)], selected_columns=columns[dataset], + tenant_ids=tenant_ids, ) ) From 655fa98fc6a61d33fee52608d0cba4802ac5a25e Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 14 Mar 2023 14:51:17 -0700 Subject: [PATCH 23/25] rest of preview --- src/sentry/rules/history/preview.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/sentry/rules/history/preview.py b/src/sentry/rules/history/preview.py index f27ed7c6b2442b..ef303c6cae58cb 100644 --- a/src/sentry/rules/history/preview.py +++ b/src/sentry/rules/history/preview.py @@ -251,7 +251,9 @@ def get_top_groups( }, has_issue_state_condition, ) - query_params.append(SnubaQueryParams(**kwargs)) + query_params.append( + SnubaQueryParams(**kwargs, tenant_ids={"organization_id": project.organization_id}) + ) groups = [] for result in bulk_raw_query(query_params, use_cache=True, referrer="preview.get_top_groups"): @@ -518,7 +520,10 @@ def get_frequency_buckets( }, ) bucket_counts = raw_query( - **kwargs, use_cache=True, referrer="preview.get_frequency_buckets" + **kwargs, + use_cache=True, + referrer="preview.get_frequency_buckets", + tenant_ids={"organization_id": project.organization_id}, ).get("data", []) for bucket in bucket_counts: From 2262665302513f6cf6db0c7cba0ed36ccc98f165 Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Tue, 14 Mar 2023 16:11:01 -0700 Subject: [PATCH 24/25] reorder outcomes param --- src/sentry/snuba/outcomes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sentry/snuba/outcomes.py b/src/sentry/snuba/outcomes.py index 5b434605499d48..2f404863d501ab 100644 --- a/src/sentry/snuba/outcomes.py +++ b/src/sentry/snuba/outcomes.py @@ -321,8 +321,8 @@ def run_outcomes_query_totals( def run_outcomes_query_timeseries( query: QueryDefinition, - tenant_ids: dict[str, Any] | None = None, referrer: str = "outcomes.timeseries", + tenant_ids: dict[str, Any] | None = None, ) -> ResultSet: """ Runs an outcomes query. By default the referrer is `outcomes.timeseries` and this should not change From ea8367a5ca9593279d54116c3e2f5de0f49dcf75 Mon Sep 17 00:00:00 2001 From: Rahul Saini Date: Wed, 15 Mar 2023 11:32:37 -0700 Subject: [PATCH 25/25] get_from_cache --- src/sentry/tasks/reprocessing2.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sentry/tasks/reprocessing2.py b/src/sentry/tasks/reprocessing2.py index fe114a02e60712..7ec8f1ff7983fd 100644 --- a/src/sentry/tasks/reprocessing2.py +++ b/src/sentry/tasks/reprocessing2.py @@ -4,8 +4,9 @@ from django.conf import settings from django.db import transaction -from sentry import eventstore, eventstream, models, nodestore +from sentry import eventstore, eventstream, nodestore from sentry.eventstore.models import Event +from sentry.models import Project from sentry.reprocessing2 import buffered_delete_old_primary_hash from sentry.tasks.base import instrumented_task, retry from sentry.tasks.process_buffer import buffer_incr @@ -64,7 +65,9 @@ def reprocess_group( batch_size=settings.SENTRY_REPROCESSING_PAGE_SIZE, state=query_state, referrer="reprocessing2.reprocess_group", - tenant_ids={"organization_id": models.Project.objects.get(id=project_id).organization_id}, + tenant_ids={ + "organization_id": Project.objects.get_from_cache(id=project_id).organization_id + }, ) if not events: