Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/sentry/features/temporary.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,6 @@ def register_temporary_features(manager: FeatureManager) -> None:
manager.add("organizations:workflow-engine-action-filters-cache", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=False)
# Enable ingestion through trusted relays only
manager.add("organizations:ingest-through-trusted-relays-only", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
# Enable metric issue UI for issue alerts
manager.add("organizations:workflow-engine-metric-issue-ui", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
# Disable issue stream detector notifications for metric issues
manager.add("organizations:workflow-engine-metric-issue-disable-issue-detector-notifications", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=False)
# Enable new workflow_engine UI (see: alerts create issues)
Expand Down
16 changes: 1 addition & 15 deletions src/sentry/incidents/grouptype.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ class MetricIssue(GroupType):
category_v2 = GroupCategory.METRIC.value
creation_quota = Quota(3600, 60, 100)
default_priority = PriorityLevel.HIGH
released = True
enable_auto_resolve = False
enable_escalation_detection = False
enable_status_change_workflow_notifications = False
Expand All @@ -375,18 +376,3 @@ class MetricIssue(GroupType):
},
},
)

@classmethod
def allow_ingest(cls, organization: Organization) -> bool:
return True

@classmethod
def allow_post_process_group(cls, organization: Organization) -> bool:
return True

@classmethod
def build_visible_feature_name(cls) -> list[str]:
return [
"organizations:workflow-engine-ui",
"organizations:workflow-engine-metric-issue-ui",
]
14 changes: 4 additions & 10 deletions src/sentry/workflow_engine/processors/detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,31 +67,25 @@ def detectors(self) -> set[Detector]:
def _is_issue_stream_detector_enabled(event_data: WorkflowEventData) -> bool:
"""
Check if the issue stream detector should be enabled for this event's group type.

Most group types enable the issue stream detector by default. MetricIssue is excluded
unless the workflow-engine-metric-issue-ui feature flag is enabled for the organization,
which allows incremental rollout of issue alerts for metric issues.
"""
group_type_id = event_data.group.type
disabled_type_ids = options.get("workflow_engine.group.type_id.disable_issue_stream_detector")
if group_type_id not in disabled_type_ids:
return True

# Metric isssues are a special case currently.
# In order to give users time to adjust to the new behavior, we allow them to disable the
# issue stream detector for metric issues via a feature flag.
if group_type_id != MetricIssue.type_id:
return False

organization = event_data.event.project.organization

has_metric_issue_ui = features.has(
"organizations:workflow-engine-metric-issue-ui", organization
)
# For most users, the issue stream detector for metric issues will be rolled out along with the metric issue UI.
# For users who find that behavior undesirable, this feature flag will disable it for them.
disable_issue_stream_detector_for_metric_issues = features.has(
"organizations:workflow-engine-metric-issue-disable-issue-detector-notifications",
organization,
)
return has_metric_issue_ui and not disable_issue_stream_detector_for_metric_issues
return not disable_issue_stream_detector_for_metric_issues


def get_detectors_for_event_data(
Expand Down
53 changes: 11 additions & 42 deletions tests/sentry/workflow_engine/processors/test_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,6 @@ def setUp(self) -> None:
self.group_event = GroupEvent.from_event(self.event, self.group)

def test_activity_update(self) -> None:
# only picks up metric detector because the group type does not enable the issue stream detector
activity = Activity.objects.create(
project=self.project,
group=self.group,
Expand All @@ -878,7 +877,7 @@ def test_activity_update(self) -> None:
result = get_detectors_for_event_data(event_data, detector=self.detector)
assert result is not None
assert result.preferred_detector == self.detector
assert result.detectors == {self.detector}
assert result.detectors == {self.issue_stream_detector, self.detector}

def test_error_group_type(self) -> None:
# default behavior for a group type is to pick up the issue stream detector
Expand All @@ -896,30 +895,6 @@ def test_metric_issue(self) -> None:
result = get_detectors_for_event_data(event_data)
assert result is not None
assert result.preferred_detector == self.detector
assert result.detectors == {self.detector}

def test_metric_issue_with_feature_flag(self) -> None:
self.group_event.occurrence = self.occurrence

event_data = WorkflowEventData(event=self.group_event, group=self.group)
with self.feature("organizations:workflow-engine-metric-issue-ui"):
result = get_detectors_for_event_data(event_data)
assert result is not None
assert result.preferred_detector == self.detector
assert result.detectors == {self.issue_stream_detector, self.detector}

def test_activity_update_with_feature_flag(self) -> None:
activity = Activity.objects.create(
project=self.project,
group=self.group,
type=ActivityType.SET_RESOLVED.value,
user_id=self.user.id,
)
event_data = WorkflowEventData(event=activity, group=self.group)
with self.feature("organizations:workflow-engine-metric-issue-ui"):
result = get_detectors_for_event_data(event_data, detector=self.detector)
assert result is not None
assert result.preferred_detector == self.detector
assert result.detectors == {self.issue_stream_detector, self.detector}

def test_metric_issue_with_disable_detector_flag(self) -> None:
Expand All @@ -928,18 +903,15 @@ def test_metric_issue_with_disable_detector_flag(self) -> None:

event_data = WorkflowEventData(event=self.group_event, group=self.group)
with self.feature(
{
"organizations:workflow-engine-metric-issue-ui": True,
"organizations:workflow-engine-metric-issue-disable-issue-detector-notifications": True,
}
"organizations:workflow-engine-metric-issue-disable-issue-detector-notifications"
):
result = get_detectors_for_event_data(event_data)
assert result is not None
assert result.preferred_detector == self.detector
assert result.detectors == {self.detector}

def test_non_metric_issue_in_disable_list_with_feature_flag(self) -> None:
"""Feature flag override only applies to MetricIssue, not other disabled group types."""
def test_non_metric_issue_in_disable_list(self) -> None:
"""Disable override only applies to MetricIssue, not other disabled group types."""
self.group.update(type=FeedbackGroup.type_id)
activity = Activity.objects.create(
project=self.project,
Expand All @@ -948,16 +920,13 @@ def test_non_metric_issue_in_disable_list_with_feature_flag(self) -> None:
user_id=self.user.id,
)
event_data = WorkflowEventData(event=activity, group=self.group)
with (
self.feature("organizations:workflow-engine-metric-issue-ui"),
self.options(
{
"workflow_engine.group.type_id.disable_issue_stream_detector": [
MetricIssue.type_id,
FeedbackGroup.type_id,
]
}
),
with self.options(
{
"workflow_engine.group.type_id.disable_issue_stream_detector": [
MetricIssue.type_id,
FeedbackGroup.type_id,
]
}
):
result = get_detectors_for_event_data(event_data)
assert result is None
Expand Down
Loading