Browse Source

feat(escalating-v2): Emit escalating metrics (#54240)

These changes from #52774 were reverting - undoing the revert.  

Update the ESCALATING_ISSUES use case during post_process as we see new
events come in.

---------

Co-authored-by: Riya Chakraborty <riya.chakraborty@sentry.io>
Snigdha Sharma 1 year ago
parent
commit
93fc8e781f

+ 2 - 0
src/sentry/conf/server.py

@@ -1378,6 +1378,8 @@ SENTRY_FEATURES = {
     "organizations:escalating-issues-msteams": False,
     # Enable archive/escalating issue workflow features in v2
     "organizations:escalating-issues-v2": False,
+    # Enable emiting escalating data to the metrics backend
+    "organizations:escalating-metrics-backend": False,
     # Allows an org to have a larger set of project ownership rules per project
     "organizations:higher-ownership-limit": False,
     # Enable Monitors (Crons) view

+ 1 - 0
src/sentry/features/__init__.py

@@ -233,6 +233,7 @@ default_manager.add("organizations:dynamic-sampling", OrganizationFeature, Featu
 default_manager.add("organizations:escalating-issues", OrganizationFeature, FeatureHandlerStrategy.INTERNAL)
 default_manager.add("organizations:escalating-issues-msteams", OrganizationFeature, FeatureHandlerStrategy.REMOTE)
 default_manager.add("organizations:escalating-issues-v2", OrganizationFeature, FeatureHandlerStrategy.INTERNAL)
+default_manager.add("organizations:escalating-metrics-backend", OrganizationFeature, FeatureHandlerStrategy.INTERNAL)
 default_manager.add("organizations:integrations-gh-invite", OrganizationFeature, FeatureHandlerStrategy.REMOTE)
 default_manager.add("organizations:event-attachments", OrganizationFeature, FeatureHandlerStrategy.INTERNAL)
 default_manager.add("organizations:global-views", OrganizationFeature, FeatureHandlerStrategy.INTERNAL)

+ 19 - 0
src/sentry/tasks/post_process.py

@@ -16,6 +16,8 @@ from sentry.exceptions import PluginError
 from sentry.issues.grouptype import GroupCategory
 from sentry.issues.issue_occurrence import IssueOccurrence
 from sentry.killswitches import killswitch_matches_context
+from sentry.sentry_metrics.client import generic_metrics_backend
+from sentry.sentry_metrics.use_case_id_registry import UseCaseID
 from sentry.signals import event_processed, issue_unignored, transaction_processed
 from sentry.silo import SiloMode
 from sentry.tasks.base import instrumented_task
@@ -116,6 +118,21 @@ def _capture_event_stats(event: Event) -> None:
     metrics.timing("events.size.data", event.size, tags=tags)
 
 
+def _update_escalating_metrics(event: Event) -> None:
+    """
+    Update metrics for escalating issues when an event is processed.
+    """
+    generic_metrics_backend.counter(
+        UseCaseID.ESCALATING_ISSUES,
+        org_id=event.project.organization_id,
+        project_id=event.project.id,
+        metric_name="event_ingested",
+        value=1,
+        tags={"group": str(event.group_id)},
+        unit=None,
+    )
+
+
 def _capture_group_stats(job: PostProcessJob) -> None:
     event = job["event"]
     if not job["group_state"]["is_new"] or not should_write_event_stats(event):
@@ -573,6 +590,8 @@ def post_process_group(
         update_event_groups(event, group_states)
         bind_organization_context(event.project.organization)
         _capture_event_stats(event)
+        if features.has("organizations:escalating-metrics-backend", event.project.organization):
+            _update_escalating_metrics(event)
 
         group_events: Mapping[int, GroupEvent] = {
             ge.group_id: ge for ge in list(event.build_group_events())

+ 8 - 0
tests/relay_integration/lang/javascript/test_plugin.py

@@ -8,6 +8,7 @@ from uuid import uuid4
 
 import pytest
 import responses
+from django.conf import settings
 from django.core.files.base import ContentFile
 from django.utils import timezone
 
@@ -1308,6 +1309,9 @@ class TestJavascriptIntegration(RelayStoreHelper):
             body=load_fixture("node_app.min.js.map"),
             content_type="application/javascript; charset=utf-8",
         )
+        responses.add_passthru(
+            settings.SENTRY_SNUBA + "/tests/entities/generic_metrics_counters/insert",
+        )
 
         data = {
             "timestamp": self.min_ago,
@@ -1383,6 +1387,10 @@ class TestJavascriptIntegration(RelayStoreHelper):
                 "<!doctype html><html><head></head><body><script>/*legit case*/</script></body></html>"
             ),
         )
+        responses.add_passthru(
+            settings.SENTRY_SNUBA + "/tests/entities/generic_metrics_counters/insert",
+        )
+
         data = {
             "timestamp": self.min_ago,
             "message": "hello",

+ 4 - 0
tests/sentry/notifications/test_notifications.py

@@ -5,6 +5,7 @@ from unittest.mock import patch
 from urllib.parse import parse_qs
 
 import responses
+from django.conf import settings
 from django.core import mail
 from django.core.mail.message import EmailMultiAlternatives
 from django.utils import timezone
@@ -106,6 +107,9 @@ class ActivityNotificationTest(APITestCase):
             status=200,
             content_type="application/json",
         )
+        responses.add_passthru(
+            settings.SENTRY_SNUBA + "/tests/entities/generic_metrics_counters/insert",
+        )
         self.name = self.user.get_display_name()
         self.short_id = self.group.qualified_short_id
 

+ 2 - 4
tests/sentry/sentry_metrics/test_snuba.py

@@ -13,7 +13,6 @@ pytestmark = pytest.mark.sentry_metrics
 class MetricsInterfaceTestCase(BaseMetricsLayerTestCase, TestCase, GenericMetricsTestMixIn):
     def setUp(self):
         super().setUp()
-        self.test_project = self.create_project()
 
 
 class SnubaMetricsInterfaceTest(MetricsInterfaceTestCase):
@@ -33,7 +32,7 @@ class SnubaMetricsInterfaceTest(MetricsInterfaceTestCase):
         generic_metrics_backend.distribution(
             self.use_case_id,
             self.organization.id,
-            self.test_project.id,
+            self.project.id,
             self.metric_name,
             [100, 200, 300],
             {},
@@ -49,7 +48,6 @@ class SnubaMetricsInterfaceTest(MetricsInterfaceTestCase):
                     metric_mri=self.get_mri(self.metric_name, "d", self.use_case_id, self.unit),
                 ),
             ],
-            project_ids=[self.test_project.id],
             groupby=[],
             orderby=[],
             limit=Limit(limit=1),
@@ -58,7 +56,7 @@ class SnubaMetricsInterfaceTest(MetricsInterfaceTestCase):
         )
 
         data = get_series(
-            [self.test_project],
+            [self.project],
             metrics_query=metrics_query,
             include_meta=True,
             use_case_id=self.use_case_id,