Skip to content

Commit

Permalink
chore(alerts): Remove more activated alerts code (#83212)
Browse files Browse the repository at this point in the history
Removes deprecated activated alerts code from the test utils and alert
creation code as well as a few other lingering spots.
  • Loading branch information
ceorourke authored Jan 10, 2025
1 parent 107638b commit f67ee46
Show file tree
Hide file tree
Showing 14 changed files with 49 additions and 329 deletions.
2 changes: 0 additions & 2 deletions src/sentry/features/temporary.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ def register_temporary_features(manager: FeatureManager):
# Organization scoped features that are in development or in customer trials. #
###############################################################################

# Enables activated alert rules
manager.add("organizations:activated-alert-rules", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
# Enable AI Issue Summary feature on the Issue Details page.
manager.add("organizations:ai-summary", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
# Enables alert creation on indexed events in UI (use for PoC/testing only)
Expand Down
1 change: 0 additions & 1 deletion src/sentry/incidents/endpoints/serializers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from .alert_rule import * # NOQA
from .alert_rule_activations import * # NOQA
from .alert_rule_trigger import * # NOQA
from .alert_rule_trigger_action import * # NOQA
from .query_subscription import * # NOQA

This file was deleted.

33 changes: 1 addition & 32 deletions src/sentry/incidents/logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from dataclasses import dataclass, replace
from datetime import datetime, timedelta, timezone
from enum import Enum, auto
from typing import TYPE_CHECKING, Any, TypedDict
from typing import Any, TypedDict
from uuid import UUID, uuid4

from django.db import router, transaction
Expand All @@ -29,7 +29,6 @@
AlertRuleActivity,
AlertRuleActivityType,
AlertRuleDetectionType,
AlertRuleMonitorTypeInt,
AlertRuleProjects,
AlertRuleSeasonality,
AlertRuleSensitivity,
Expand All @@ -38,10 +37,6 @@
AlertRuleTrigger,
AlertRuleTriggerAction,
)
from sentry.incidents.models.alert_rule_activations import (
AlertRuleActivationCondition,
AlertRuleActivations,
)
from sentry.incidents.models.incident import (
Incident,
IncidentActivity,
Expand Down Expand Up @@ -105,10 +100,6 @@
from sentry.utils.audit import create_audit_entry_from_user
from sentry.utils.snuba import is_measurement

if TYPE_CHECKING:
from sentry.incidents.utils.types import AlertRuleActivationConditionType


# We can return an incident as "windowed" which returns a range of points around the start of the incident
# It attempts to center the start of the incident, only showing earlier data if there isn't enough time
# after the incident started to display the correct start date.
Expand Down Expand Up @@ -153,7 +144,6 @@ def create_incident(
projects: Collection[Project] = (),
user: RpcUser | None = None,
alert_rule: AlertRule | None = None,
activation: AlertRuleActivations | None = None,
subscription: QuerySubscription | None = None,
) -> Incident:
if date_detected is None:
Expand All @@ -169,7 +159,6 @@ def create_incident(
date_started=date_started,
date_detected=date_detected,
alert_rule=alert_rule,
activation=activation,
subscription=subscription,
)
if projects:
Expand Down Expand Up @@ -513,8 +502,6 @@ def create_alert_rule(
user: RpcUser | None = None,
event_types: Collection[SnubaQueryEventType.EventType] = (),
comparison_delta: int | None = None,
monitor_type: AlertRuleMonitorTypeInt = AlertRuleMonitorTypeInt.CONTINUOUS,
activation_condition: AlertRuleActivationConditionType | None = None,
description: str | None = None,
sensitivity: AlertRuleSensitivity | None = None,
seasonality: AlertRuleSeasonality | None = None,
Expand Down Expand Up @@ -556,9 +543,6 @@ def create_alert_rule(
if detection_type == AlertRuleDetectionType.DYNAMIC.value and not has_anomaly_detection:
raise ResourceDoesNotExist("Your organization does not have access to this feature.")

if monitor_type == AlertRuleMonitorTypeInt.ACTIVATED and not activation_condition:
raise ValidationError("Activation condition required for activated alert rule")

if detection_type == AlertRuleDetectionType.DYNAMIC:
resolution = time_window
# NOTE: we hardcode seasonality for EA
Expand Down Expand Up @@ -617,7 +601,6 @@ def create_alert_rule(
resolve_threshold=resolve_threshold,
threshold_period=threshold_period,
comparison_delta=comparison_delta,
monitor_type=monitor_type,
description=description,
sensitivity=sensitivity,
seasonality=seasonality,
Expand All @@ -639,12 +622,6 @@ def create_alert_rule(
event=audit_log.get_event_id("ALERT_RULE_ADD"),
)

if monitor_type == AlertRuleMonitorTypeInt.ACTIVATED and activation_condition:
# NOTE: if monitor_type is activated, activation_condition is required
AlertRuleActivationCondition.objects.create(
alert_rule=alert_rule, condition_type=activation_condition.value
)

# initialize projects join table for alert rules
arps = [AlertRuleProjects(alert_rule=alert_rule, project=project) for project in projects]
AlertRuleProjects.objects.bulk_create(arps)
Expand Down Expand Up @@ -745,7 +722,6 @@ def update_alert_rule(
user: RpcUser | None = None,
event_types: Collection[SnubaQueryEventType.EventType] | None = None,
comparison_delta: int | None | NotSet = NOT_SET,
monitor_type: AlertRuleMonitorTypeInt | None = None,
description: str | None = None,
sensitivity: AlertRuleSensitivity | None | NotSet = NOT_SET,
seasonality: AlertRuleSeasonality | None | NotSet = NOT_SET,
Expand Down Expand Up @@ -807,9 +783,6 @@ def update_alert_rule(
updated_query_fields["dataset"] = dataset
if query_type is not None:
updated_query_fields["query_type"] = query_type
if monitor_type is not None:
# TODO: determine how to convert activated alert into continuous alert and vice versa
pass
if event_types is not None:
updated_query_fields["event_types"] = event_types
if owner is not NOT_SET:
Expand Down Expand Up @@ -1080,10 +1053,6 @@ class AlertRuleTriggerLabelAlreadyUsedError(Exception):
pass


class AlertRuleActivationConditionLabelAlreadyUsedError(Exception):
pass


class ProjectsNotAssociatedWithAlertRuleError(Exception):
def __init__(self, project_slugs: Collection[str]) -> None:
self.project_slugs = project_slugs
Expand Down
1 change: 1 addition & 0 deletions src/sentry/incidents/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .alert_rule_activations import * # NOQA
54 changes: 0 additions & 54 deletions src/sentry/incidents/models/alert_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@
from sentry.db.models.fields.hybrid_cloud_foreign_key import HybridCloudForeignKey
from sentry.db.models.manager.base import BaseManager
from sentry.db.models.manager.base_query_set import BaseQuerySet
from sentry.incidents.models.alert_rule_activations import AlertRuleActivations
from sentry.incidents.models.incident import Incident, IncidentStatus, IncidentTrigger
from sentry.incidents.utils.constants import INCIDENTS_SNUBA_SUBSCRIPTION_TYPE
from sentry.incidents.utils.types import AlertRuleActivationConditionType
from sentry.models.organization import Organization
from sentry.models.project import Project
from sentry.models.team import Team
Expand All @@ -40,7 +37,6 @@
)
from sentry.seer.anomaly_detection.delete_rule import delete_rule_in_seer
from sentry.snuba.models import QuerySubscription
from sentry.snuba.subscriptions import bulk_create_snuba_subscriptions
from sentry.types.actor import Actor
from sentry.users.services.user import RpcUser
from sentry.users.services.user.service import user_service
Expand Down Expand Up @@ -254,56 +250,6 @@ def owner(self, actor: Actor | None) -> None:
def get_audit_log_data(self) -> dict[str, Any]:
return {"label": self.name}

def subscribe_projects(
self,
projects: Iterable[Project],
monitor_type: AlertRuleMonitorTypeInt = AlertRuleMonitorTypeInt.CONTINUOUS,
query_extra: str | None = None,
activation_condition: AlertRuleActivationConditionType | None = None,
activator: str | None = None,
) -> list[QuerySubscription]:
"""
Subscribes a list of projects to the alert rule instance
:return: The list of created subscriptions
"""

logger.info(
"Subscribing projects to alert rule",
extra={
"alert_rule.monitor_type": self.monitor_type,
"conditional_monitor_type": monitor_type,
"query_extra": query_extra,
},
)
# NOTE: AlertRuleMonitorTypeInt.ACTIVATED will be conditionally subscribed given activation triggers
# On activated subscription, additional query parameters will be added to the constructed query in Snuba
created_subscriptions = []
if self.monitor_type == monitor_type:
# NOTE: QuerySubscriptions hold reference to Projects which should match the AlertRule's project reference
created_subscriptions = bulk_create_snuba_subscriptions(
projects,
INCIDENTS_SNUBA_SUBSCRIPTION_TYPE,
self.snuba_query,
query_extra=query_extra,
)
if self.monitor_type == AlertRuleMonitorTypeInt.ACTIVATED:
# NOTE: Activated Alert Rules are conditionally subscribed
# Meaning at time of subscription, the rule must have been activated
if not activator or activation_condition is None:
raise Exception(
"Alert activations require an activation condition and activator reference"
)

for subscription in created_subscriptions:
AlertRuleActivations.objects.create(
alert_rule=self,
query_subscription=subscription,
condition_type=activation_condition.value,
activator=activator,
)

return created_subscriptions


class AlertRuleTriggerManager(BaseManager["AlertRuleTrigger"]):
CACHE_KEY = "alert_rule_triggers:alert_rule:%s"
Expand Down
6 changes: 0 additions & 6 deletions src/sentry/integrations/metric_alerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,8 @@ def metric_alert_attachment_info(
text += f"\nThreshold: {alert_rule.detection_type.title()}"

date_started = None
activation = None
if selected_incident:
date_started = selected_incident.date_started
activation = selected_incident.activation

last_triggered_date = None
if latest_incident:
Expand All @@ -239,8 +237,4 @@ def metric_alert_attachment_info(
"date_started": date_started,
"last_triggered_date": last_triggered_date,
"title_link": title_link,
"activator": (activation.activator if activation else ""),
"condition_type": (
activation.condition_type if activation else None
), # 0 = release creation, 1 = deploy creation
}
34 changes: 1 addition & 33 deletions src/sentry/testutils/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,10 @@
query_datasets_to_type,
)
from sentry.incidents.models.alert_rule import (
AlertRule,
AlertRuleDetectionType,
AlertRuleMonitorTypeInt,
AlertRuleThresholdType,
AlertRuleTriggerAction,
)
from sentry.incidents.models.alert_rule_activations import AlertRuleActivations
from sentry.incidents.models.incident import (
Incident,
IncidentActivity,
Expand All @@ -57,7 +54,6 @@
IncidentType,
TriggerStatus,
)
from sentry.incidents.utils.types import AlertRuleActivationConditionType
from sentry.integrations.models.doc_integration import DocIntegration
from sentry.integrations.models.doc_integration_avatar import DocIntegrationAvatar
from sentry.integrations.models.external_actor import ExternalActor
Expand Down Expand Up @@ -145,7 +141,7 @@
from sentry.signals import project_created
from sentry.silo.base import SiloMode
from sentry.snuba.dataset import Dataset
from sentry.snuba.models import QuerySubscription, QuerySubscriptionDataSourceHandler
from sentry.snuba.models import QuerySubscriptionDataSourceHandler
from sentry.tempest.models import MessageType as TempestMessageType
from sentry.tempest.models import TempestCredentials
from sentry.testutils.outbox import outbox_runner
Expand Down Expand Up @@ -1547,7 +1543,6 @@ def create_incident(
date_closed=None,
alert_rule=None,
subscription=None,
activation=None,
):
if not title:
title = petname.generate(2, " ", letters=10).title()
Expand All @@ -1567,7 +1562,6 @@ def create_incident(
date_closed=timezone.now() if date_closed is not None else date_closed,
type=IncidentType.ALERT_TRIGGERED.value,
subscription=subscription,
activation=activation,
)
for project in projects:
IncidentProject.objects.create(incident=incident, project=project)
Expand Down Expand Up @@ -1601,8 +1595,6 @@ def create_alert_rule(
user=None,
event_types=None,
comparison_delta=None,
monitor_type=AlertRuleMonitorTypeInt.CONTINUOUS,
activation_condition=AlertRuleActivationConditionType.RELEASE_CREATION,
description=None,
sensitivity=None,
seasonality=None,
Expand Down Expand Up @@ -1631,8 +1623,6 @@ def create_alert_rule(
user=user,
event_types=event_types,
comparison_delta=comparison_delta,
monitor_type=monitor_type,
activation_condition=activation_condition,
description=description,
sensitivity=sensitivity,
seasonality=seasonality,
Expand All @@ -1644,28 +1634,6 @@ def create_alert_rule(

return alert_rule

@staticmethod
@assume_test_silo_mode(SiloMode.REGION)
def create_alert_rule_activation(
alert_rule: AlertRule,
query_subscription: QuerySubscription,
metric_value: int | None = None,
finished_at: datetime | None = None,
activation_condition: AlertRuleActivationConditionType = AlertRuleActivationConditionType.RELEASE_CREATION,
):

with transaction.atomic(router.db_for_write(AlertRuleActivations)):
activation = AlertRuleActivations.objects.create(
alert_rule=alert_rule,
finished_at=finished_at,
metric_value=metric_value,
query_subscription=query_subscription,
condition_type=activation_condition.value,
activator="testing",
)

return activation

@staticmethod
@assume_test_silo_mode(SiloMode.REGION)
def create_alert_rule_trigger(alert_rule, label=None, alert_threshold=100):
Expand Down
Loading

0 comments on commit f67ee46

Please sign in to comment.