diff --git a/src/sentry/analytics/events/eventuser_snuba_for_projects.py b/src/sentry/analytics/events/eventuser_snuba_for_projects.py index 4a1e842a5eb6a9..8ee70ede2a9686 100644 --- a/src/sentry/analytics/events/eventuser_snuba_for_projects.py +++ b/src/sentry/analytics/events/eventuser_snuba_for_projects.py @@ -1,15 +1,12 @@ from sentry import analytics +@analytics.eventclass("eventuser_snuba.for_projects") class EventUserSnubaForProjects(analytics.Event): - type = "eventuser_snuba.for_projects" - - attributes = ( - analytics.Attribute("project_ids", type=list), - analytics.Attribute("total_tries", type=int), - analytics.Attribute("total_rows_returned", required=True, type=int), - analytics.Attribute("total_time_ms", type=int), - ) + project_ids: list[int] + total_tries: int + total_rows_returned: int + total_time_ms: int analytics.register(EventUserSnubaForProjects) diff --git a/src/sentry/analytics/events/eventuser_snuba_query.py b/src/sentry/analytics/events/eventuser_snuba_query.py index 4921596450053d..950539844b9e9a 100644 --- a/src/sentry/analytics/events/eventuser_snuba_query.py +++ b/src/sentry/analytics/events/eventuser_snuba_query.py @@ -1,17 +1,14 @@ from sentry import analytics +@analytics.eventclass("eventuser_snuba.query") class EventUserSnubaQuery(analytics.Event): - type = "eventuser_snuba.query" - - attributes = ( - analytics.Attribute("project_ids", type=list), - analytics.Attribute("query"), - analytics.Attribute("query_try", type=int), - analytics.Attribute("count_rows_returned", required=True, type=int), - analytics.Attribute("count_rows_filtered", required=True, type=int), - analytics.Attribute("query_time_ms", type=int), - ) + project_ids: list[int] + query: str + query_try: int + count_rows_returned: int + count_rows_filtered: int + query_time_ms: int analytics.register(EventUserSnubaQuery) diff --git a/src/sentry/analytics/events/grouping_parameterization_experiment.py b/src/sentry/analytics/events/grouping_parameterization_experiment.py index 4a9ab7022e90bc..df4713ddb0eb29 100644 --- a/src/sentry/analytics/events/grouping_parameterization_experiment.py +++ b/src/sentry/analytics/events/grouping_parameterization_experiment.py @@ -1,14 +1,11 @@ from sentry import analytics +@analytics.eventclass("grouping.experiments.parameterization") class GroupingParameterizationExperiment(analytics.Event): - type = "grouping.experiments.parameterization" - - attributes = ( - analytics.Attribute("experiment_name"), - analytics.Attribute("project_id"), - analytics.Attribute("event_id"), - ) + experiment_name: str + project_id: str + event_id: str analytics.register(GroupingParameterizationExperiment) diff --git a/src/sentry/analytics/events/notifications_settings_updated.py b/src/sentry/analytics/events/notifications_settings_updated.py index f3472279d89221..2c5bba2eaccb47 100644 --- a/src/sentry/analytics/events/notifications_settings_updated.py +++ b/src/sentry/analytics/events/notifications_settings_updated.py @@ -1,14 +1,11 @@ from sentry import analytics +@analytics.eventclass("notifications.settings_updated") class NotificationSettingsUpdated(analytics.Event): - type = "notifications.settings_updated" - - attributes = ( - analytics.Attribute("target_type"), - analytics.Attribute("actor_id", required=False), - analytics.Attribute("id"), - ) + target_type: str + actor_id: str | None = None + id: str analytics.register(NotificationSettingsUpdated) diff --git a/src/sentry/mail/analytics.py b/src/sentry/mail/analytics.py index 6c1b649e3a1c38..1e19ea18a01b6c 100644 --- a/src/sentry/mail/analytics.py +++ b/src/sentry/mail/analytics.py @@ -2,21 +2,18 @@ # TODO: should have same base class as SlackIntegrationNotificationSent +@analytics.eventclass("integrations.email.notification_sent") class EmailNotificationSent(analytics.Event): - type = "integrations.email.notification_sent" - - attributes = ( - analytics.Attribute("organization_id"), - analytics.Attribute("project_id", required=False), - analytics.Attribute("category"), - analytics.Attribute("actor_id", required=False), - analytics.Attribute("user_id", required=False), - analytics.Attribute("group_id", required=False), - analytics.Attribute("id"), - analytics.Attribute("actor_type"), - analytics.Attribute("notification_uuid"), - analytics.Attribute("alert_id", required=False), - ) + organization_id: str + project_id: str | None = None + category: str + actor_id: str | None = None + user_id: str | None = None + group_id: str | None = None + id: str + actor_type: str + notification_uuid: str + alert_id: str | None = None analytics.register(EmailNotificationSent) diff --git a/src/sentry/utils/eventuser.py b/src/sentry/utils/eventuser.py index 2a3b5333863910..c8d21379806055 100644 --- a/src/sentry/utils/eventuser.py +++ b/src/sentry/utils/eventuser.py @@ -25,6 +25,8 @@ ) from sentry import analytics +from sentry.analytics.events.eventuser_snuba_for_projects import EventUserSnubaForProjects +from sentry.analytics.events.eventuser_snuba_query import EventUserSnubaQuery from sentry.eventstore.models import Event, GroupEvent from sentry.models.project import Project from sentry.snuba.dataset import Dataset, EntityKey @@ -233,13 +235,14 @@ def for_projects( query_end_time = time.time() analytics.record( - "eventuser_snuba.query", - project_ids=[p.id for p in projects], - query=query.print(), - query_try=tries, - count_rows_returned=len(data_results), - count_rows_filtered=len(data_results) - len(unique_event_users), - query_time_ms=int((query_end_time - query_start_time) * 1000), + EventUserSnubaQuery( + project_ids=[p.id for p in projects], + query=query.print(), + query_try=tries, + count_rows_returned=len(data_results), + count_rows_filtered=len(data_results) - len(unique_event_users), + query_time_ms=int((query_end_time - query_start_time) * 1000), + ) ) tries += 1 if ( @@ -252,11 +255,12 @@ def for_projects( end_time = time.time() analytics.record( - "eventuser_snuba.for_projects", - project_ids=[p.id for p in projects], - total_tries=tries, - total_rows_returned=len(full_results), - total_time_ms=int((end_time - start_time) * 1000), + EventUserSnubaForProjects( + project_ids=[p.id for p in projects], + total_tries=tries, + total_rows_returned=len(full_results), + total_time_ms=int((end_time - start_time) * 1000), + ) ) if result_limit: diff --git a/tests/sentry/utils/test_eventuser.py b/tests/sentry/utils/test_eventuser.py index 809be39a74fab1..7b75dce4c0d443 100644 --- a/tests/sentry/utils/test_eventuser.py +++ b/tests/sentry/utils/test_eventuser.py @@ -2,12 +2,14 @@ from datetime import timedelta from unittest import mock -from unittest.mock import call from django.utils import timezone from snuba_sdk import BooleanOp +from sentry.analytics.events.eventuser_snuba_for_projects import EventUserSnubaForProjects +from sentry.analytics.events.eventuser_snuba_query import EventUserSnubaQuery from sentry.testutils.cases import APITestCase, SnubaTestCase +from sentry.testutils.helpers.analytics import assert_analytics_events_recorded from sentry.testutils.helpers.datetime import before_now, freeze_time from sentry.utils.eventuser import EventUser @@ -70,10 +72,10 @@ def test_for_projects_query_filter_id(self, mock_record): assert euser[0].user_ident == self.event_2.data.get("user").get("id") assert euser[0].email == self.event_2.data.get("user").get("email") - mock_record.assert_has_calls( + assert_analytics_events_recorded( + mock_record, [ - call( - "eventuser_snuba.query", + EventUserSnubaQuery( project_ids=[self.project.id], query=f"MATCH (events)\nSELECT project_id, ip_address_v6, ip_address_v4, user_id, user_name, " f"user_email, max(timestamp) AS `latest_timestamp`\nBY project_id, ip_address_v6, " @@ -88,8 +90,7 @@ def test_for_projects_query_filter_id(self, mock_record): count_rows_filtered=0, query_time_ms=0, ), - call( - "eventuser_snuba.for_projects", + EventUserSnubaForProjects( project_ids=[self.project.id], total_tries=1, total_rows_returned=1, @@ -281,10 +282,10 @@ def test_for_projects_query_with_multiple_eventuser_entries_different_ips_query_ assert eusers[1].email == self.event_3.data.get("user").get("email") assert eusers[1].ip_address == self.event_3.data.get("user").get("ip_address") - mock_record.assert_has_calls( + assert_analytics_events_recorded( + mock_record, [ - call( - "eventuser_snuba.query", + EventUserSnubaQuery( project_ids=[self.project.id], query=f"MATCH (events)\nSELECT project_id, ip_address_v6, ip_address_v4, user_id, user_name, " f"user_email, max(timestamp) AS `latest_timestamp`\nBY project_id, ip_address_v6, " @@ -298,8 +299,7 @@ def test_for_projects_query_with_multiple_eventuser_entries_different_ips_query_ count_rows_filtered=19, query_time_ms=0, ), - call( - "eventuser_snuba.for_projects", + EventUserSnubaForProjects( project_ids=[self.project.id], total_tries=1, total_rows_returned=2, @@ -361,10 +361,10 @@ def test_for_projects_multiple_query(self, mock_record): assert eusers[1].email == email_2 assert eusers[1].ip_address == "2001:db8:0:85a3::ac1f:8005" - mock_record.assert_has_calls( + assert_analytics_events_recorded( + mock_record, [ - call( - "eventuser_snuba.query", + EventUserSnubaQuery( project_ids=[self.project.id], query=f"MATCH (events)\nSELECT project_id, ip_address_v6, ip_address_v4, user_id, user_name, " f"user_email, max(timestamp) AS `latest_timestamp`\nBY project_id, ip_address_v6, " @@ -379,8 +379,7 @@ def test_for_projects_multiple_query(self, mock_record): count_rows_filtered=4, query_time_ms=0, ), - call( - "eventuser_snuba.query", + EventUserSnubaQuery( project_ids=[self.project.id], query=f"MATCH (events)\nSELECT project_id, ip_address_v6, ip_address_v4, user_id, user_name, " f"user_email, max(timestamp) AS `latest_timestamp`\nBY project_id, ip_address_v6, " @@ -395,8 +394,7 @@ def test_for_projects_multiple_query(self, mock_record): count_rows_filtered=3, query_time_ms=0, ), - call( - "eventuser_snuba.for_projects", + EventUserSnubaForProjects( project_ids=[self.project.id], total_tries=2, total_rows_returned=2,