Skip to content

Commit

Permalink
Add limit to API for Alert Rules (#70596)
Browse files Browse the repository at this point in the history
## Description
Fixes: #67195

Adds the `x-sentry-rule-limit` header to the list views for alert rules
(both the combined-rules and metric alert api).

I tried adding an indicator to the UI, but it was pretty difficult to
tell which page we're on in the UI, since we're handling it on the
backend with a `Link`. Rather than blocking the API fix on trying to
figure out the UI, i figure it's better to get this out and we can add
to the UI later.

![Screenshot 2024-05-09 at 11 39
43 AM](https://github.com/getsentry/sentry/assets/1569818/3cb0d796-95ad-4f87-8344-88d9599b6c79)
  • Loading branch information
saponifi3d committed May 9, 2024
1 parent 26d4c83 commit e8f6cb0
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/sentry/api/helpers/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
MAX_QUERY_SUBSCRIPTIONS_HEADER = "X-Sentry-Alert-Rule-Limit"
ALERT_RULES_COUNT_HEADER = "X-Sentry-Alert-Rule-Hits"
11 changes: 9 additions & 2 deletions src/sentry/incidents/endpoints/organization_alert_rule_index.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from copy import deepcopy
from datetime import UTC, datetime

from django.conf import settings
from django.db.models import DateTimeField, IntegerField, OuterRef, Q, Subquery, Value
from django.db.models.functions import Coalesce
from drf_spectacular.utils import extend_schema, extend_schema_serializer
Expand All @@ -15,6 +16,7 @@
from sentry.api.bases.organization import OrganizationAlertRulePermission, OrganizationEndpoint
from sentry.api.exceptions import ResourceDoesNotExist
from sentry.api.fields.actor import ActorField
from sentry.api.helpers.constants import ALERT_RULES_COUNT_HEADER, MAX_QUERY_SUBSCRIPTIONS_HEADER
from sentry.api.paginator import (
CombinedQuerysetIntermediary,
CombinedQuerysetPaginator,
Expand Down Expand Up @@ -70,7 +72,7 @@ def fetch_metric_alert(self, request, organization, project=None):
if monitor_type is not None:
alert_rules = alert_rules.filter(monitor_type=monitor_type)

return self.paginate(
response = self.paginate(
request,
queryset=alert_rules,
order_by="-date_added",
Expand All @@ -79,6 +81,10 @@ def fetch_metric_alert(self, request, organization, project=None):
default_per_page=25,
)

response[ALERT_RULES_COUNT_HEADER] = len(alert_rules)
response[MAX_QUERY_SUBSCRIPTIONS_HEADER] = settings.MAX_QUERY_SUBSCRIPTIONS_PER_ORG
return response

def create_metric_alert(self, request, organization, project=None):
if not features.has("organizations:incidents", organization, actor=request.user):
raise ResourceDoesNotExist
Expand Down Expand Up @@ -278,7 +284,8 @@ def get(self, request: Request, organization) -> Response:
case_insensitive=case_insensitive,
)
response["X-Sentry-Issue-Rule-Hits"] = issue_rules_count
response["X-Sentry-Alert-Rule-Hits"] = alert_rules_count
response[ALERT_RULES_COUNT_HEADER] = alert_rules_count
response[MAX_QUERY_SUBSCRIPTIONS_HEADER] = settings.MAX_QUERY_SUBSCRIPTIONS_PER_ORG
return response


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from rest_framework import status

from sentry import audit_log
from sentry.api.helpers.constants import ALERT_RULES_COUNT_HEADER, MAX_QUERY_SUBSCRIPTIONS_HEADER
from sentry.api.serializers import serialize
from sentry.incidents.models.alert_rule import (
AlertRule,
Expand Down Expand Up @@ -122,6 +123,18 @@ def test_filter_by_monitor_type(self):
assert serialize([alert_rule2]) not in resp.data
assert resp.data == serialize([alert_rule1])

def test_response_headers(self):
self.create_team(organization=self.organization, members=[self.user])
self.create_alert_rule(monitor_type=AlertRuleMonitorType.ACTIVATED)
self.create_alert_rule(monitor_type=AlertRuleMonitorType.CONTINUOUS)
self.login_as(self.user)

with self.feature("organizations:incidents"):
resp = self.get_response(self.organization.slug)

assert resp[ALERT_RULES_COUNT_HEADER] == "2"
assert resp[MAX_QUERY_SUBSCRIPTIONS_HEADER] == "1000"

def test_simple_with_activation(self):
self.create_team(organization=self.organization, members=[self.user])
alert_rule = self.create_alert_rule()
Expand Down

0 comments on commit e8f6cb0

Please sign in to comment.