From c10c837b119825cbeef747d49b06c250130b4dc3 Mon Sep 17 00:00:00 2001 From: Shruthilaya Jaganathan Date: Mon, 1 Dec 2025 14:16:31 -0500 Subject: [PATCH 1/6] feat: Special extrapolation on count alerts only --- .../explore/translation/alerts_translation.py | 20 +- .../translation/test_alerts_translation.py | 340 +++++++++++++++++- 2 files changed, 354 insertions(+), 6 deletions(-) diff --git a/src/sentry/explore/translation/alerts_translation.py b/src/sentry/explore/translation/alerts_translation.py index 2b7c82d79c3de0..30601f3fefb854 100644 --- a/src/sentry/explore/translation/alerts_translation.py +++ b/src/sentry/explore/translation/alerts_translation.py @@ -8,6 +8,7 @@ from sentry.incidents.models.alert_rule import AlertRuleDetectionType from sentry.incidents.subscription_processor import MetricIssueDetectorConfig from sentry.incidents.utils.types import DATA_SOURCE_SNUBA_QUERY_SUBSCRIPTION +from sentry.search.events.fields import parse_function from sentry.seer.anomaly_detection.store_data import SeerMethod from sentry.seer.anomaly_detection.store_data_workflow_engine import ( handle_send_historical_data_to_seer, @@ -26,6 +27,13 @@ logger = logging.getLogger(__name__) +COUNT_BASED_ALERT_AGGREAGTES = [ + "count", + "failure_count", + "sum", + "count_if", +] + def snapshot_snuba_query(snuba_query: SnubaQuery): if snuba_query.dataset in [Dataset.PerformanceMetrics.value, Dataset.Transactions.value]: @@ -93,10 +101,14 @@ def translate_detector_and_update_subscription_in_snuba(snuba_query: SnubaQuery) snuba_query.query = translated_query snuba_query.dataset = Dataset.EventsAnalyticsPlatform.value - if snapshot["dataset"] == Dataset.PerformanceMetrics.value: - snuba_query.extrapolation_mode = ExtrapolationMode.SERVER_WEIGHTED.value - elif snapshot["dataset"] == Dataset.Transactions.value: - snuba_query.extrapolation_mode = ExtrapolationMode.NONE.value + function_name, _, _ = parse_function(old_aggregate) + if function_name in COUNT_BASED_ALERT_AGGREAGTES: + if snapshot["dataset"] == Dataset.PerformanceMetrics.value: + snuba_query.extrapolation_mode = ExtrapolationMode.SERVER_WEIGHTED.value + elif snapshot["dataset"] == Dataset.Transactions.value: + snuba_query.extrapolation_mode = ExtrapolationMode.NONE.value + else: + snuba_query.extrapolation_mode = ExtrapolationMode.CLIENT_AND_SERVER_WEIGHTED.value with atomic_transaction( using=( diff --git a/tests/sentry/explore/translation/test_alerts_translation.py b/tests/sentry/explore/translation/test_alerts_translation.py index 70d853c25b64ae..239c916da85320 100644 --- a/tests/sentry/explore/translation/test_alerts_translation.py +++ b/tests/sentry/explore/translation/test_alerts_translation.py @@ -264,7 +264,7 @@ def test_translate_alert_rule_p95(self, mock_create_rpc) -> None: assert snuba_query.dataset == Dataset.EventsAnalyticsPlatform.value assert snuba_query.aggregate == "p95(span.duration)" assert snuba_query.query == "(transaction.method:GET) AND is_transaction:1" - assert snuba_query.extrapolation_mode == ExtrapolationMode.NONE.value + assert snuba_query.extrapolation_mode == ExtrapolationMode.CLIENT_AND_SERVER_WEIGHTED.value event_types = list( SnubaQueryEventType.objects.filter(snuba_query=snuba_query).values_list( @@ -330,7 +330,7 @@ def test_translate_alert_rule_count_unique(self, mock_create_rpc) -> None: assert snuba_query.dataset == Dataset.EventsAnalyticsPlatform.value assert snuba_query.aggregate == "count_unique(user)" assert snuba_query.query == "(transaction:/api/*) AND is_transaction:1" - assert snuba_query.extrapolation_mode == ExtrapolationMode.SERVER_WEIGHTED.value + assert snuba_query.extrapolation_mode == ExtrapolationMode.CLIENT_AND_SERVER_WEIGHTED.value assert mock_create_rpc.called call_args = mock_create_rpc.call_args @@ -744,3 +744,339 @@ def test_rollback_anomaly_detection_alert( assert project_arg.id == self.project.id assert seer_method_arg == SeerMethod.UPDATE assert event_types_arg == [SnubaQueryEventType.EventType.TRANSACTION] + + @with_feature("organizations:migrate-transaction-alerts-to-spans") + @patch("sentry.snuba.tasks._create_rpc_in_snuba") + def test_extrapolation_mode_failure_count_performance_metrics(self, mock_create_rpc) -> None: + mock_create_rpc.return_value = "test-subscription-id" + + snuba_query = create_snuba_query( + query_type=SnubaQuery.Type.PERFORMANCE, + dataset=Dataset.PerformanceMetrics, + query="", + aggregate="failure_count()", + time_window=timedelta(minutes=10), + environment=None, + event_types=[SnubaQueryEventType.EventType.TRANSACTION], + resolution=timedelta(minutes=1), + ) + + create_snuba_subscription( + project=self.project, + subscription_type=INCIDENTS_SNUBA_SUBSCRIPTION_TYPE, + snuba_query=snuba_query, + ) + + data_source = self.create_data_source( + organization=self.org, + source_id=str(snuba_query.id), + type=DATA_SOURCE_SNUBA_QUERY_SUBSCRIPTION, + ) + + detector_data_condition_group = self.create_data_condition_group( + organization=self.org, + ) + + detector = self.create_detector( + name="Test Detector", + type=MetricIssue.slug, + project=self.project, + config={"detection_type": AlertRuleDetectionType.STATIC.value}, + workflow_condition_group=detector_data_condition_group, + ) + + data_source.detectors.add(detector) + + with self.tasks(): + translate_detector_and_update_subscription_in_snuba(snuba_query) + snuba_query.refresh_from_db() + + assert snuba_query.extrapolation_mode == ExtrapolationMode.SERVER_WEIGHTED.value + + @with_feature("organizations:migrate-transaction-alerts-to-spans") + @patch("sentry.snuba.tasks._create_rpc_in_snuba") + def test_extrapolation_mode_failure_count_transactions(self, mock_create_rpc) -> None: + mock_create_rpc.return_value = "test-subscription-id" + + snuba_query = create_snuba_query( + query_type=SnubaQuery.Type.PERFORMANCE, + dataset=Dataset.Transactions, + query="", + aggregate="failure_count()", + time_window=timedelta(minutes=10), + environment=None, + event_types=[SnubaQueryEventType.EventType.TRANSACTION], + resolution=timedelta(minutes=1), + ) + + create_snuba_subscription( + project=self.project, + subscription_type=INCIDENTS_SNUBA_SUBSCRIPTION_TYPE, + snuba_query=snuba_query, + ) + + data_source = self.create_data_source( + organization=self.org, + source_id=str(snuba_query.id), + type=DATA_SOURCE_SNUBA_QUERY_SUBSCRIPTION, + ) + + detector_data_condition_group = self.create_data_condition_group( + organization=self.org, + ) + + detector = self.create_detector( + name="Test Detector", + type=MetricIssue.slug, + project=self.project, + config={"detection_type": AlertRuleDetectionType.STATIC.value}, + workflow_condition_group=detector_data_condition_group, + ) + + data_source.detectors.add(detector) + + with self.tasks(): + translate_detector_and_update_subscription_in_snuba(snuba_query) + snuba_query.refresh_from_db() + + assert snuba_query.extrapolation_mode == ExtrapolationMode.NONE.value + + @with_feature("organizations:migrate-transaction-alerts-to-spans") + @patch("sentry.snuba.tasks._create_rpc_in_snuba") + def test_extrapolation_mode_sum_performance_metrics(self, mock_create_rpc) -> None: + mock_create_rpc.return_value = "test-subscription-id" + + snuba_query = create_snuba_query( + query_type=SnubaQuery.Type.PERFORMANCE, + dataset=Dataset.PerformanceMetrics, + query="", + aggregate="sum(transaction.duration)", + time_window=timedelta(minutes=10), + environment=None, + event_types=[SnubaQueryEventType.EventType.TRANSACTION], + resolution=timedelta(minutes=1), + ) + + create_snuba_subscription( + project=self.project, + subscription_type=INCIDENTS_SNUBA_SUBSCRIPTION_TYPE, + snuba_query=snuba_query, + ) + + data_source = self.create_data_source( + organization=self.org, + source_id=str(snuba_query.id), + type=DATA_SOURCE_SNUBA_QUERY_SUBSCRIPTION, + ) + + detector_data_condition_group = self.create_data_condition_group( + organization=self.org, + ) + + detector = self.create_detector( + name="Test Detector", + type=MetricIssue.slug, + project=self.project, + config={"detection_type": AlertRuleDetectionType.STATIC.value}, + workflow_condition_group=detector_data_condition_group, + ) + + data_source.detectors.add(detector) + + with self.tasks(): + translate_detector_and_update_subscription_in_snuba(snuba_query) + snuba_query.refresh_from_db() + + assert snuba_query.extrapolation_mode == ExtrapolationMode.SERVER_WEIGHTED.value + + @with_feature("organizations:migrate-transaction-alerts-to-spans") + @patch("sentry.snuba.tasks._create_rpc_in_snuba") + def test_extrapolation_mode_sum_transactions(self, mock_create_rpc) -> None: + mock_create_rpc.return_value = "test-subscription-id" + + snuba_query = create_snuba_query( + query_type=SnubaQuery.Type.PERFORMANCE, + dataset=Dataset.Transactions, + query="", + aggregate="sum(transaction.duration)", + time_window=timedelta(minutes=10), + environment=None, + event_types=[SnubaQueryEventType.EventType.TRANSACTION], + resolution=timedelta(minutes=1), + ) + + create_snuba_subscription( + project=self.project, + subscription_type=INCIDENTS_SNUBA_SUBSCRIPTION_TYPE, + snuba_query=snuba_query, + ) + + data_source = self.create_data_source( + organization=self.org, + source_id=str(snuba_query.id), + type=DATA_SOURCE_SNUBA_QUERY_SUBSCRIPTION, + ) + + detector_data_condition_group = self.create_data_condition_group( + organization=self.org, + ) + + detector = self.create_detector( + name="Test Detector", + type=MetricIssue.slug, + project=self.project, + config={"detection_type": AlertRuleDetectionType.STATIC.value}, + workflow_condition_group=detector_data_condition_group, + ) + + data_source.detectors.add(detector) + + with self.tasks(): + translate_detector_and_update_subscription_in_snuba(snuba_query) + snuba_query.refresh_from_db() + + assert snuba_query.extrapolation_mode == ExtrapolationMode.NONE.value + + @with_feature("organizations:migrate-transaction-alerts-to-spans") + @patch("sentry.snuba.tasks._create_rpc_in_snuba") + def test_extrapolation_mode_avg_performance_metrics(self, mock_create_rpc) -> None: + mock_create_rpc.return_value = "test-subscription-id" + + snuba_query = create_snuba_query( + query_type=SnubaQuery.Type.PERFORMANCE, + dataset=Dataset.PerformanceMetrics, + query="", + aggregate="avg(transaction.duration)", + time_window=timedelta(minutes=10), + environment=None, + event_types=[SnubaQueryEventType.EventType.TRANSACTION], + resolution=timedelta(minutes=1), + ) + + create_snuba_subscription( + project=self.project, + subscription_type=INCIDENTS_SNUBA_SUBSCRIPTION_TYPE, + snuba_query=snuba_query, + ) + + data_source = self.create_data_source( + organization=self.org, + source_id=str(snuba_query.id), + type=DATA_SOURCE_SNUBA_QUERY_SUBSCRIPTION, + ) + + detector_data_condition_group = self.create_data_condition_group( + organization=self.org, + ) + + detector = self.create_detector( + name="Test Detector", + type=MetricIssue.slug, + project=self.project, + config={"detection_type": AlertRuleDetectionType.STATIC.value}, + workflow_condition_group=detector_data_condition_group, + ) + + data_source.detectors.add(detector) + + with self.tasks(): + translate_detector_and_update_subscription_in_snuba(snuba_query) + snuba_query.refresh_from_db() + + assert snuba_query.extrapolation_mode == ExtrapolationMode.CLIENT_AND_SERVER_WEIGHTED.value + + @with_feature("organizations:migrate-transaction-alerts-to-spans") + @patch("sentry.snuba.tasks._create_rpc_in_snuba") + def test_extrapolation_mode_p50_transactions(self, mock_create_rpc) -> None: + mock_create_rpc.return_value = "test-subscription-id" + + snuba_query = create_snuba_query( + query_type=SnubaQuery.Type.PERFORMANCE, + dataset=Dataset.Transactions, + query="", + aggregate="p50(transaction.duration)", + time_window=timedelta(minutes=10), + environment=None, + event_types=[SnubaQueryEventType.EventType.TRANSACTION], + resolution=timedelta(minutes=1), + ) + + create_snuba_subscription( + project=self.project, + subscription_type=INCIDENTS_SNUBA_SUBSCRIPTION_TYPE, + snuba_query=snuba_query, + ) + + data_source = self.create_data_source( + organization=self.org, + source_id=str(snuba_query.id), + type=DATA_SOURCE_SNUBA_QUERY_SUBSCRIPTION, + ) + + detector_data_condition_group = self.create_data_condition_group( + organization=self.org, + ) + + detector = self.create_detector( + name="Test Detector", + type=MetricIssue.slug, + project=self.project, + config={"detection_type": AlertRuleDetectionType.STATIC.value}, + workflow_condition_group=detector_data_condition_group, + ) + + data_source.detectors.add(detector) + + with self.tasks(): + translate_detector_and_update_subscription_in_snuba(snuba_query) + snuba_query.refresh_from_db() + + assert snuba_query.extrapolation_mode == ExtrapolationMode.CLIENT_AND_SERVER_WEIGHTED.value + + @with_feature("organizations:migrate-transaction-alerts-to-spans") + @patch("sentry.snuba.tasks._create_rpc_in_snuba") + def test_extrapolation_mode_max_performance_metrics(self, mock_create_rpc) -> None: + mock_create_rpc.return_value = "test-subscription-id" + + snuba_query = create_snuba_query( + query_type=SnubaQuery.Type.PERFORMANCE, + dataset=Dataset.PerformanceMetrics, + query="", + aggregate="max(transaction.duration)", + time_window=timedelta(minutes=10), + environment=None, + event_types=[SnubaQueryEventType.EventType.TRANSACTION], + resolution=timedelta(minutes=1), + ) + + create_snuba_subscription( + project=self.project, + subscription_type=INCIDENTS_SNUBA_SUBSCRIPTION_TYPE, + snuba_query=snuba_query, + ) + + data_source = self.create_data_source( + organization=self.org, + source_id=str(snuba_query.id), + type=DATA_SOURCE_SNUBA_QUERY_SUBSCRIPTION, + ) + + detector_data_condition_group = self.create_data_condition_group( + organization=self.org, + ) + + detector = self.create_detector( + name="Test Detector", + type=MetricIssue.slug, + project=self.project, + config={"detection_type": AlertRuleDetectionType.STATIC.value}, + workflow_condition_group=detector_data_condition_group, + ) + + data_source.detectors.add(detector) + + with self.tasks(): + translate_detector_and_update_subscription_in_snuba(snuba_query) + snuba_query.refresh_from_db() + + assert snuba_query.extrapolation_mode == ExtrapolationMode.CLIENT_AND_SERVER_WEIGHTED.value From 46121b2be89e35a8c0aa5ea11727447d45a6aacc Mon Sep 17 00:00:00 2001 From: Shruthilaya Jaganathan Date: Mon, 1 Dec 2025 14:24:42 -0500 Subject: [PATCH 2/6] tests --- .../translation/test_alerts_translation.py | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/tests/sentry/explore/translation/test_alerts_translation.py b/tests/sentry/explore/translation/test_alerts_translation.py index 239c916da85320..29dd8ace778c53 100644 --- a/tests/sentry/explore/translation/test_alerts_translation.py +++ b/tests/sentry/explore/translation/test_alerts_translation.py @@ -937,6 +937,102 @@ def test_extrapolation_mode_sum_transactions(self, mock_create_rpc) -> None: assert snuba_query.extrapolation_mode == ExtrapolationMode.NONE.value + @with_feature("organizations:migrate-transaction-alerts-to-spans") + @patch("sentry.snuba.tasks._create_rpc_in_snuba") + def test_extrapolation_mode_count_if_performance_metrics(self, mock_create_rpc) -> None: + mock_create_rpc.return_value = "test-subscription-id" + + snuba_query = create_snuba_query( + query_type=SnubaQuery.Type.PERFORMANCE, + dataset=Dataset.PerformanceMetrics, + query="", + aggregate="count_if(transaction.duration,greater,100)", + time_window=timedelta(minutes=10), + environment=None, + event_types=[SnubaQueryEventType.EventType.TRANSACTION], + resolution=timedelta(minutes=1), + ) + + create_snuba_subscription( + project=self.project, + subscription_type=INCIDENTS_SNUBA_SUBSCRIPTION_TYPE, + snuba_query=snuba_query, + ) + + data_source = self.create_data_source( + organization=self.org, + source_id=str(snuba_query.id), + type=DATA_SOURCE_SNUBA_QUERY_SUBSCRIPTION, + ) + + detector_data_condition_group = self.create_data_condition_group( + organization=self.org, + ) + + detector = self.create_detector( + name="Test Detector", + type=MetricIssue.slug, + project=self.project, + config={"detection_type": AlertRuleDetectionType.STATIC.value}, + workflow_condition_group=detector_data_condition_group, + ) + + data_source.detectors.add(detector) + + with self.tasks(): + translate_detector_and_update_subscription_in_snuba(snuba_query) + snuba_query.refresh_from_db() + + assert snuba_query.extrapolation_mode == ExtrapolationMode.SERVER_WEIGHTED.value + + @with_feature("organizations:migrate-transaction-alerts-to-spans") + @patch("sentry.snuba.tasks._create_rpc_in_snuba") + def test_extrapolation_mode_count_if_transactions(self, mock_create_rpc) -> None: + mock_create_rpc.return_value = "test-subscription-id" + + snuba_query = create_snuba_query( + query_type=SnubaQuery.Type.PERFORMANCE, + dataset=Dataset.Transactions, + query="", + aggregate="count_if(transaction.duration,greater,100)", + time_window=timedelta(minutes=10), + environment=None, + event_types=[SnubaQueryEventType.EventType.TRANSACTION], + resolution=timedelta(minutes=1), + ) + + create_snuba_subscription( + project=self.project, + subscription_type=INCIDENTS_SNUBA_SUBSCRIPTION_TYPE, + snuba_query=snuba_query, + ) + + data_source = self.create_data_source( + organization=self.org, + source_id=str(snuba_query.id), + type=DATA_SOURCE_SNUBA_QUERY_SUBSCRIPTION, + ) + + detector_data_condition_group = self.create_data_condition_group( + organization=self.org, + ) + + detector = self.create_detector( + name="Test Detector", + type=MetricIssue.slug, + project=self.project, + config={"detection_type": AlertRuleDetectionType.STATIC.value}, + workflow_condition_group=detector_data_condition_group, + ) + + data_source.detectors.add(detector) + + with self.tasks(): + translate_detector_and_update_subscription_in_snuba(snuba_query) + snuba_query.refresh_from_db() + + assert snuba_query.extrapolation_mode == ExtrapolationMode.NONE.value + @with_feature("organizations:migrate-transaction-alerts-to-spans") @patch("sentry.snuba.tasks._create_rpc_in_snuba") def test_extrapolation_mode_avg_performance_metrics(self, mock_create_rpc) -> None: From 6cf7ffa3244fc59c441a9fbbecbdbccacb633d3d Mon Sep 17 00:00:00 2001 From: Shruthilaya Jaganathan Date: Mon, 1 Dec 2025 14:31:30 -0500 Subject: [PATCH 3/6] too many tests --- .../translation/test_alerts_translation.py | 192 ------------------ 1 file changed, 192 deletions(-) diff --git a/tests/sentry/explore/translation/test_alerts_translation.py b/tests/sentry/explore/translation/test_alerts_translation.py index 29dd8ace778c53..a79e953ce02ae9 100644 --- a/tests/sentry/explore/translation/test_alerts_translation.py +++ b/tests/sentry/explore/translation/test_alerts_translation.py @@ -745,102 +745,6 @@ def test_rollback_anomaly_detection_alert( assert seer_method_arg == SeerMethod.UPDATE assert event_types_arg == [SnubaQueryEventType.EventType.TRANSACTION] - @with_feature("organizations:migrate-transaction-alerts-to-spans") - @patch("sentry.snuba.tasks._create_rpc_in_snuba") - def test_extrapolation_mode_failure_count_performance_metrics(self, mock_create_rpc) -> None: - mock_create_rpc.return_value = "test-subscription-id" - - snuba_query = create_snuba_query( - query_type=SnubaQuery.Type.PERFORMANCE, - dataset=Dataset.PerformanceMetrics, - query="", - aggregate="failure_count()", - time_window=timedelta(minutes=10), - environment=None, - event_types=[SnubaQueryEventType.EventType.TRANSACTION], - resolution=timedelta(minutes=1), - ) - - create_snuba_subscription( - project=self.project, - subscription_type=INCIDENTS_SNUBA_SUBSCRIPTION_TYPE, - snuba_query=snuba_query, - ) - - data_source = self.create_data_source( - organization=self.org, - source_id=str(snuba_query.id), - type=DATA_SOURCE_SNUBA_QUERY_SUBSCRIPTION, - ) - - detector_data_condition_group = self.create_data_condition_group( - organization=self.org, - ) - - detector = self.create_detector( - name="Test Detector", - type=MetricIssue.slug, - project=self.project, - config={"detection_type": AlertRuleDetectionType.STATIC.value}, - workflow_condition_group=detector_data_condition_group, - ) - - data_source.detectors.add(detector) - - with self.tasks(): - translate_detector_and_update_subscription_in_snuba(snuba_query) - snuba_query.refresh_from_db() - - assert snuba_query.extrapolation_mode == ExtrapolationMode.SERVER_WEIGHTED.value - - @with_feature("organizations:migrate-transaction-alerts-to-spans") - @patch("sentry.snuba.tasks._create_rpc_in_snuba") - def test_extrapolation_mode_failure_count_transactions(self, mock_create_rpc) -> None: - mock_create_rpc.return_value = "test-subscription-id" - - snuba_query = create_snuba_query( - query_type=SnubaQuery.Type.PERFORMANCE, - dataset=Dataset.Transactions, - query="", - aggregate="failure_count()", - time_window=timedelta(minutes=10), - environment=None, - event_types=[SnubaQueryEventType.EventType.TRANSACTION], - resolution=timedelta(minutes=1), - ) - - create_snuba_subscription( - project=self.project, - subscription_type=INCIDENTS_SNUBA_SUBSCRIPTION_TYPE, - snuba_query=snuba_query, - ) - - data_source = self.create_data_source( - organization=self.org, - source_id=str(snuba_query.id), - type=DATA_SOURCE_SNUBA_QUERY_SUBSCRIPTION, - ) - - detector_data_condition_group = self.create_data_condition_group( - organization=self.org, - ) - - detector = self.create_detector( - name="Test Detector", - type=MetricIssue.slug, - project=self.project, - config={"detection_type": AlertRuleDetectionType.STATIC.value}, - workflow_condition_group=detector_data_condition_group, - ) - - data_source.detectors.add(detector) - - with self.tasks(): - translate_detector_and_update_subscription_in_snuba(snuba_query) - snuba_query.refresh_from_db() - - assert snuba_query.extrapolation_mode == ExtrapolationMode.NONE.value - @with_feature("organizations:migrate-transaction-alerts-to-spans") @patch("sentry.snuba.tasks._create_rpc_in_snuba") def test_extrapolation_mode_sum_performance_metrics(self, mock_create_rpc) -> None: @@ -1033,54 +937,6 @@ def test_extrapolation_mode_count_if_transactions(self, mock_create_rpc) -> None assert snuba_query.extrapolation_mode == ExtrapolationMode.NONE.value - @with_feature("organizations:migrate-transaction-alerts-to-spans") - @patch("sentry.snuba.tasks._create_rpc_in_snuba") - def test_extrapolation_mode_avg_performance_metrics(self, mock_create_rpc) -> None: - mock_create_rpc.return_value = "test-subscription-id" - - snuba_query = create_snuba_query( - query_type=SnubaQuery.Type.PERFORMANCE, - dataset=Dataset.PerformanceMetrics, - query="", - aggregate="avg(transaction.duration)", - time_window=timedelta(minutes=10), - environment=None, - event_types=[SnubaQueryEventType.EventType.TRANSACTION], - resolution=timedelta(minutes=1), - ) - - create_snuba_subscription( - project=self.project, - subscription_type=INCIDENTS_SNUBA_SUBSCRIPTION_TYPE, - snuba_query=snuba_query, - ) - - data_source = self.create_data_source( - organization=self.org, - source_id=str(snuba_query.id), - type=DATA_SOURCE_SNUBA_QUERY_SUBSCRIPTION, - ) - - detector_data_condition_group = self.create_data_condition_group( - organization=self.org, - ) - - detector = self.create_detector( - name="Test Detector", - type=MetricIssue.slug, - project=self.project, - config={"detection_type": AlertRuleDetectionType.STATIC.value}, - workflow_condition_group=detector_data_condition_group, - ) - - data_source.detectors.add(detector) - - with self.tasks(): - translate_detector_and_update_subscription_in_snuba(snuba_query) - snuba_query.refresh_from_db() - - assert snuba_query.extrapolation_mode == ExtrapolationMode.CLIENT_AND_SERVER_WEIGHTED.value - @with_feature("organizations:migrate-transaction-alerts-to-spans") @patch("sentry.snuba.tasks._create_rpc_in_snuba") def test_extrapolation_mode_p50_transactions(self, mock_create_rpc) -> None: @@ -1128,51 +984,3 @@ def test_extrapolation_mode_p50_transactions(self, mock_create_rpc) -> None: snuba_query.refresh_from_db() assert snuba_query.extrapolation_mode == ExtrapolationMode.CLIENT_AND_SERVER_WEIGHTED.value - - @with_feature("organizations:migrate-transaction-alerts-to-spans") - @patch("sentry.snuba.tasks._create_rpc_in_snuba") - def test_extrapolation_mode_max_performance_metrics(self, mock_create_rpc) -> None: - mock_create_rpc.return_value = "test-subscription-id" - - snuba_query = create_snuba_query( - query_type=SnubaQuery.Type.PERFORMANCE, - dataset=Dataset.PerformanceMetrics, - query="", - aggregate="max(transaction.duration)", - time_window=timedelta(minutes=10), - environment=None, - event_types=[SnubaQueryEventType.EventType.TRANSACTION], - resolution=timedelta(minutes=1), - ) - - create_snuba_subscription( - project=self.project, - subscription_type=INCIDENTS_SNUBA_SUBSCRIPTION_TYPE, - snuba_query=snuba_query, - ) - - data_source = self.create_data_source( - organization=self.org, - source_id=str(snuba_query.id), - type=DATA_SOURCE_SNUBA_QUERY_SUBSCRIPTION, - ) - - detector_data_condition_group = self.create_data_condition_group( - organization=self.org, - ) - - detector = self.create_detector( - name="Test Detector", - type=MetricIssue.slug, - project=self.project, - config={"detection_type": AlertRuleDetectionType.STATIC.value}, - workflow_condition_group=detector_data_condition_group, - ) - - data_source.detectors.add(detector) - - with self.tasks(): - translate_detector_and_update_subscription_in_snuba(snuba_query) - snuba_query.refresh_from_db() - - assert snuba_query.extrapolation_mode == ExtrapolationMode.CLIENT_AND_SERVER_WEIGHTED.value From 8b1ebfff2d296f211ab6d46a285a3a1d12935524 Mon Sep 17 00:00:00 2001 From: Shruthilaya Jaganathan Date: Mon, 1 Dec 2025 14:40:01 -0500 Subject: [PATCH 4/6] add count unique to the list --- src/sentry/explore/translation/alerts_translation.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sentry/explore/translation/alerts_translation.py b/src/sentry/explore/translation/alerts_translation.py index 30601f3fefb854..d3534c577d3b3a 100644 --- a/src/sentry/explore/translation/alerts_translation.py +++ b/src/sentry/explore/translation/alerts_translation.py @@ -32,6 +32,7 @@ "failure_count", "sum", "count_if", + "count_unique", ] From e84988eeae7ae48bf19fb7b08b23f363e4ef918c Mon Sep 17 00:00:00 2001 From: Shruthilaya Jaganathan Date: Mon, 1 Dec 2025 14:45:58 -0500 Subject: [PATCH 5/6] fix test --- tests/sentry/explore/translation/test_alerts_translation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/sentry/explore/translation/test_alerts_translation.py b/tests/sentry/explore/translation/test_alerts_translation.py index a79e953ce02ae9..39798426524504 100644 --- a/tests/sentry/explore/translation/test_alerts_translation.py +++ b/tests/sentry/explore/translation/test_alerts_translation.py @@ -330,7 +330,7 @@ def test_translate_alert_rule_count_unique(self, mock_create_rpc) -> None: assert snuba_query.dataset == Dataset.EventsAnalyticsPlatform.value assert snuba_query.aggregate == "count_unique(user)" assert snuba_query.query == "(transaction:/api/*) AND is_transaction:1" - assert snuba_query.extrapolation_mode == ExtrapolationMode.CLIENT_AND_SERVER_WEIGHTED.value + assert snuba_query.extrapolation_mode == ExtrapolationMode.NONE.value assert mock_create_rpc.called call_args = mock_create_rpc.call_args From c4d36bf3744297df7634326e14f39617e8a097e7 Mon Sep 17 00:00:00 2001 From: Shruthilaya Jaganathan Date: Mon, 1 Dec 2025 14:47:39 -0500 Subject: [PATCH 6/6] fix test --- tests/sentry/explore/translation/test_alerts_translation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/sentry/explore/translation/test_alerts_translation.py b/tests/sentry/explore/translation/test_alerts_translation.py index 39798426524504..8adfe1f0426862 100644 --- a/tests/sentry/explore/translation/test_alerts_translation.py +++ b/tests/sentry/explore/translation/test_alerts_translation.py @@ -330,7 +330,7 @@ def test_translate_alert_rule_count_unique(self, mock_create_rpc) -> None: assert snuba_query.dataset == Dataset.EventsAnalyticsPlatform.value assert snuba_query.aggregate == "count_unique(user)" assert snuba_query.query == "(transaction:/api/*) AND is_transaction:1" - assert snuba_query.extrapolation_mode == ExtrapolationMode.NONE.value + assert snuba_query.extrapolation_mode == ExtrapolationMode.SERVER_WEIGHTED.value assert mock_create_rpc.called call_args = mock_create_rpc.call_args