From 82f346bb2b692e5c2261ecf7cf8e78c340d81483 Mon Sep 17 00:00:00 2001 From: Scott Cooper Date: Tue, 12 Sep 2023 17:53:31 -0700 Subject: [PATCH] feat(alerts): Add `alert.sent` analytics for issue alerts --- src/sentry/notifications/notifications/digest.py | 16 +++++++++++++++- src/sentry/notifications/notifications/rules.py | 16 +++++++++++++++- tests/sentry/mail/test_adapter.py | 12 +++++++++++- .../notifications/notifications/test_digests.py | 12 +++++++++++- 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/sentry/notifications/notifications/digest.py b/src/sentry/notifications/notifications/digest.py index 64334c7aeb705d..5ab046288df190 100644 --- a/src/sentry/notifications/notifications/digest.py +++ b/src/sentry/notifications/notifications/digest.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, Any, Mapping, MutableMapping, Sequence from urllib.parse import urlencode -from sentry import features +from sentry import analytics, features from sentry.db.models import Model from sentry.digests import Digest from sentry.digests.utils import ( @@ -229,3 +229,17 @@ def get_log_params(self, recipient: RpcActor) -> Mapping[str, Any]: "alert_id": alert_id, **super().get_log_params(recipient), } + + def record_notification_sent(self, recipient: RpcActor, provider: ExternalProviders) -> None: + super().record_notification_sent(recipient, provider) + log_params = self.get_log_params(recipient) + analytics.record( + "alert.sent", + organization_id=self.organization.id, + project_id=self.project.id, + provider=provider.name, + alert_id=log_params["alert_id"] if log_params["alert_id"] else "", + alert_type="issue_alert", + external_id=str(recipient.id), + notification_uuid=self.notification_uuid, + ) diff --git a/src/sentry/notifications/notifications/rules.py b/src/sentry/notifications/notifications/rules.py index 2f4cfbcd89b946..2de213c57adb3e 100644 --- a/src/sentry/notifications/notifications/rules.py +++ b/src/sentry/notifications/notifications/rules.py @@ -7,7 +7,7 @@ import pytz -from sentry import features +from sentry import analytics, features from sentry.db.models import Model from sentry.eventstore.models import GroupEvent from sentry.issues.grouptype import GROUP_CATEGORIES_CUSTOM_EMAIL, GroupCategory @@ -294,3 +294,17 @@ def get_log_params(self, recipient: RpcActor) -> Mapping[str, Any]: "alert_id": self.rules[0].id if self.rules else None, **super().get_log_params(recipient), } + + def record_notification_sent(self, recipient: RpcActor, provider: ExternalProviders) -> None: + super().record_notification_sent(recipient, provider) + log_params = self.get_log_params(recipient) + analytics.record( + "alert.sent", + organization_id=self.organization.id, + project_id=self.project.id, + provider=provider.name, + alert_id=log_params["alert_id"] if log_params["alert_id"] else "", + alert_type="issue_alert", + external_id=str(recipient.id), + notification_uuid=self.notification_uuid, + ) diff --git a/tests/sentry/mail/test_adapter.py b/tests/sentry/mail/test_adapter.py index 2c5fa4d5ab73f1..31034d69f62688 100644 --- a/tests/sentry/mail/test_adapter.py +++ b/tests/sentry/mail/test_adapter.py @@ -191,7 +191,7 @@ def test_simple_notification(self, mock_record): assert isinstance(msg.alternatives[0][0], str) assert "my rule" in msg.alternatives[0][0] assert "notification_uuid" in msg.body - mock_record.assert_called_with( + mock_record.assert_any_call( "integrations.email.notification_sent", category="issue_alert", target_type=ANY, @@ -206,6 +206,16 @@ def test_simple_notification(self, mock_record): notification_uuid=ANY, alert_id=rule.id, ) + mock_record.assert_called_with( + "alert.sent", + organization_id=self.organization.id, + project_id=self.project.id, + provider="email", + alert_id=rule.id, + alert_type="issue_alert", + external_id=ANY, + notification_uuid=ANY, + ) def test_simple_snooze(self): """Test that notification for alert snoozed by user is not send to that user.""" diff --git a/tests/sentry/notifications/notifications/test_digests.py b/tests/sentry/notifications/notifications/test_digests.py index a195dbb3b9e0c6..4bb53a3b2ce87b 100644 --- a/tests/sentry/notifications/notifications/test_digests.py +++ b/tests/sentry/notifications/notifications/test_digests.py @@ -103,7 +103,7 @@ def test_sends_digest_to_every_member(self, mock_record): assert "N+1 Query" in mail.outbox[0].body assert "oh no" in mail.outbox[0].body assert self.build_occurrence_data()["issue_title"] in mail.outbox[0].body - mock_record.assert_called_with( + mock_record.assert_any_call( "integrations.email.notification_sent", category="digest", notification_uuid=ANY, @@ -118,6 +118,16 @@ def test_sends_digest_to_every_member(self, mock_record): group_id=None, user_id=ANY, ) + mock_record.assert_called_with( + "alert.sent", + organization_id=self.organization.id, + project_id=self.project.id, + provider="email", + alert_id=self.rule.id, + alert_type="issue_alert", + external_id=ANY, + notification_uuid=ANY, + ) def test_sends_alert_rule_notification_to_each_member(self): """Test that if there is only one event it is sent as a regular alert rule notification"""