diff --git a/src/sentry/incidents/logic.py b/src/sentry/incidents/logic.py index 5f192bd2e11b64..cc94bb93c3d750 100644 --- a/src/sentry/incidents/logic.py +++ b/src/sentry/incidents/logic.py @@ -643,10 +643,6 @@ def create_alert_rule( **_owner_kwargs_from_actor(owner), ) - if alert_rule.detection_type == AlertRuleDetectionType.DYNAMIC.value: - # NOTE: if adding a new metric alert type, take care to check that it's handled here - send_new_rule_data(alert_rule, projects[0], snuba_query) - if user: create_audit_entry_from_user( user, @@ -664,6 +660,10 @@ def create_alert_rule( # NOTE: This constructs the query in snuba subscribe_projects_to_alert_rule(alert_rule, projects) + if alert_rule.detection_type == AlertRuleDetectionType.DYNAMIC.value: + # NOTE: if adding a new metric alert type, take care to check that it's handled here + send_new_rule_data(alert_rule, projects[0], snuba_query) + # Activity is an audit log of what's happened with this alert rule AlertRuleActivity.objects.create( alert_rule=alert_rule, diff --git a/src/sentry/seer/anomaly_detection/store_data.py b/src/sentry/seer/anomaly_detection/store_data.py index 8511c49383eeee..306f600f853a73 100644 --- a/src/sentry/seer/anomaly_detection/store_data.py +++ b/src/sentry/seer/anomaly_detection/store_data.py @@ -17,6 +17,7 @@ from sentry.seer.anomaly_detection.types import ( AlertInSeer, AnomalyDetectionConfig, + DataSourceType, StoreDataRequest, StoreDataResponse, TimeSeriesPoint, @@ -191,13 +192,21 @@ def send_historical_data_to_seer( # this won't happen because we've already gone through the serializer, but mypy insists raise ValidationError("Missing expected configuration for a dynamic alert.") + query_subscription = snuba_query.subscriptions.first() + if query_subscription is None: + raise ValidationError("No QuerySubscription found for snuba query ID") + anomaly_detection_config = AnomalyDetectionConfig( time_period=window_min, sensitivity=alert_rule.sensitivity, direction=translate_direction(alert_rule.threshold_type), expected_seasonality=alert_rule.seasonality, ) - alert = AlertInSeer(id=alert_rule.id) + alert = AlertInSeer( + id=alert_rule.id, + source_id=query_subscription.id, + source_type=DataSourceType.SNUBA_QUERY_SUBSCRIPTION, + ) body = StoreDataRequest( organization_id=alert_rule.organization.id, project_id=project.id, diff --git a/tests/sentry/incidents/test_logic.py b/tests/sentry/incidents/test_logic.py index da286bab95b862..ae6167d49ad35f 100644 --- a/tests/sentry/incidents/test_logic.py +++ b/tests/sentry/incidents/test_logic.py @@ -97,6 +97,7 @@ from sentry.testutils.helpers.features import with_feature from sentry.testutils.silo import assume_test_silo_mode, assume_test_silo_mode_of from sentry.types.actor import Actor +from sentry.utils import json from sentry.workflow_engine.models.detector import Detector pytestmark = [pytest.mark.sentry_metrics] @@ -663,6 +664,12 @@ def test_create_alert_rule_anomaly_detection(self, mock_seer_request: MagicMock) ) assert mock_seer_request.call_count == 1 + call_args_str = mock_seer_request.call_args_list[0].kwargs["body"].decode("utf-8") + assert json.loads(call_args_str)["alert"] == { + "id": alert_rule.id, + "source_id": alert_rule.snuba_query.subscriptions.get().id, + "source_type": 1, + } assert alert_rule.name == self.dynamic_metric_alert_settings["name"] assert alert_rule.user_id is None assert alert_rule.team_id is None