diff --git a/src/sentry/analytics/events/first_event_sent.py b/src/sentry/analytics/events/first_event_sent.py index 79895ee9c78ad8..e10988565fc9c3 100644 --- a/src/sentry/analytics/events/first_event_sent.py +++ b/src/sentry/analytics/events/first_event_sent.py @@ -2,18 +2,15 @@ # first error for an organization +@analytics.eventclass("first_event.sent") class FirstEventSentEvent(analytics.Event): - type = "first_event.sent" - - attributes = ( - analytics.Attribute("user_id"), - analytics.Attribute("organization_id"), - analytics.Attribute("project_id"), - analytics.Attribute("platform", required=False), - analytics.Attribute("url", required=False), - analytics.Attribute("has_minified_stack_trace", required=False), - analytics.Attribute("project_platform", required=False), - ) + user_id: str + organization_id: str + project_id: str + platform: str | None = None + url: str | None = None + has_minified_stack_trace: str | None = None + project_platform: str | None = None # first error for a project diff --git a/src/sentry/analytics/events/issue_alert_fired.py b/src/sentry/analytics/events/issue_alert_fired.py index 80d9f46a8a070b..1cae521651153c 100644 --- a/src/sentry/analytics/events/issue_alert_fired.py +++ b/src/sentry/analytics/events/issue_alert_fired.py @@ -1,15 +1,12 @@ from sentry import analytics +@analytics.eventclass("issue_alert.fired") class IssueAlertFiredEvent(analytics.Event): - type = "issue_alert.fired" - - attributes = ( - analytics.Attribute("issue_id"), - analytics.Attribute("project_id"), - analytics.Attribute("organization_id"), - analytics.Attribute("rule_id"), - ) + issue_id: str + project_id: str + organization_id: str + rule_id: str analytics.register(IssueAlertFiredEvent) diff --git a/src/sentry/analytics/events/issue_auto_resolved.py b/src/sentry/analytics/events/issue_auto_resolved.py index 513fca6651afee..2fef5e42c692a0 100644 --- a/src/sentry/analytics/events/issue_auto_resolved.py +++ b/src/sentry/analytics/events/issue_auto_resolved.py @@ -1,16 +1,13 @@ from sentry import analytics +@analytics.eventclass("issue.auto_resolved") class IssueAutoResolvedEvent(analytics.Event): - type = "issue.auto_resolved" - - attributes = ( - analytics.Attribute("project_id", required=False), - analytics.Attribute("organization_id"), - analytics.Attribute("group_id"), - analytics.Attribute("issue_category", required=False), - analytics.Attribute("issue_type", required=False), - ) + project_id: str | None = None + organization_id: str + group_id: str + issue_category: str | None = None + issue_type: str | None = None analytics.register(IssueAutoResolvedEvent) diff --git a/src/sentry/analytics/events/manual_issue_assignment.py b/src/sentry/analytics/events/manual_issue_assignment.py index 5b16a778f741d9..3c86e293efdbd0 100644 --- a/src/sentry/analytics/events/manual_issue_assignment.py +++ b/src/sentry/analytics/events/manual_issue_assignment.py @@ -1,16 +1,13 @@ from sentry import analytics +@analytics.eventclass("manual.issue_assignment") class ManualIssueAssignment(analytics.Event): - type = "manual.issue_assignment" - - attributes = ( - analytics.Attribute("organization_id"), - analytics.Attribute("project_id"), - analytics.Attribute("group_id"), - analytics.Attribute("assigned_by", required=False), - analytics.Attribute("had_to_deassign", required=False), - ) + organization_id: str + project_id: str + group_id: str + assigned_by: str | None = None + had_to_deassign: str | None = None analytics.register(ManualIssueAssignment) diff --git a/src/sentry/api/helpers/group_index/update.py b/src/sentry/api/helpers/group_index/update.py index 8d252f8190aec2..861e7035aa0d04 100644 --- a/src/sentry/api/helpers/group_index/update.py +++ b/src/sentry/api/helpers/group_index/update.py @@ -18,6 +18,7 @@ from rest_framework.response import Response from sentry import analytics, features, options +from sentry.analytics.events.manual_issue_assignment import ManualIssueAssignment from sentry.api.serializers import serialize from sentry.api.serializers.models.actor import ActorSerializer, ActorSerializerResponse from sentry.db.models.query import create_or_update @@ -1032,23 +1033,25 @@ def handle_assigned_to( group, resolved_actor, acting_user, extra=extra ) analytics.record( - "manual.issue_assignment", - organization_id=project_lookup[group.project_id].organization_id, - project_id=group.project_id, - group_id=group.id, - assigned_by=assigned_by, - had_to_deassign=assignment["updated_assignment"], + ManualIssueAssignment( + organization_id=project_lookup[group.project_id].organization_id, + project_id=group.project_id, + group_id=group.id, + assigned_by=assigned_by, + had_to_deassign=assignment["updated_assignment"], + ) ) return serialize(resolved_actor, acting_user, ActorSerializer()) else: for group in group_list: GroupAssignee.objects.deassign(group, acting_user) analytics.record( - "manual.issue_assignment", - organization_id=project_lookup[group.project_id].organization_id, - project_id=group.project_id, - group_id=group.id, - assigned_by=assigned_by, - had_to_deassign=True, + ManualIssueAssignment( + organization_id=project_lookup[group.project_id].organization_id, + project_id=group.project_id, + group_id=group.id, + assigned_by=assigned_by, + had_to_deassign=True, + ) ) return None diff --git a/src/sentry/receivers/onboarding.py b/src/sentry/receivers/onboarding.py index f2ad6b7158cd74..51c4e49bbcc3bc 100644 --- a/src/sentry/receivers/onboarding.py +++ b/src/sentry/receivers/onboarding.py @@ -7,6 +7,7 @@ from django.db.models import F from sentry import analytics +from sentry.analytics.events.first_event_sent import FirstEventSentEvent from sentry.integrations.base import IntegrationDomain, get_integration_types from sentry.integrations.services.integration import RpcIntegration, integration_service from sentry.models.organization import Organization @@ -154,12 +155,13 @@ def record_first_event(project, event, **kwargs): if completed: analytics.record( - "first_event.sent", - user_id=owner_id, - organization_id=project.organization_id, - project_id=project.id, - platform=event.platform, - project_platform=project.platform, + FirstEventSentEvent( + user_id=owner_id, + organization_id=project.organization_id, + project_id=project.id, + platform=event.platform, + project_platform=project.platform, + ) ) diff --git a/src/sentry/rules/processing/processor.py b/src/sentry/rules/processing/processor.py index 99f9f053f17b63..0e6654a795c94d 100644 --- a/src/sentry/rules/processing/processor.py +++ b/src/sentry/rules/processing/processor.py @@ -12,6 +12,7 @@ from django.utils import timezone from sentry import analytics, buffer, features +from sentry.analytics.events.issue_alert_fired import IssueAlertFiredEvent from sentry.eventstore.models import GroupEvent from sentry.models.environment import Environment from sentry.models.group import Group @@ -390,11 +391,12 @@ def apply_rule(self, rule: Rule, status: GroupRuleStatus) -> None: if randrange(10) == 0: analytics.record( - "issue_alert.fired", - issue_id=self.group.id, - project_id=rule.project.id, - organization_id=rule.project.organization.id, - rule_id=rule.id, + IssueAlertFiredEvent( + issue_id=self.group.id, + project_id=rule.project.id, + organization_id=rule.project.organization.id, + rule_id=rule.id, + ) ) if features.has( diff --git a/src/sentry/tasks/auto_resolve_issues.py b/src/sentry/tasks/auto_resolve_issues.py index a9a6dae7bfe0c4..97d73188b278c4 100644 --- a/src/sentry/tasks/auto_resolve_issues.py +++ b/src/sentry/tasks/auto_resolve_issues.py @@ -8,6 +8,7 @@ from django.utils import timezone as django_timezone from sentry import analytics +from sentry.analytics.events.issue_auto_resolved import IssueAutoResolvedEvent from sentry.integrations.tasks.kick_off_status_syncs import kick_off_status_syncs from sentry.issues import grouptype from sentry.models.activity import Activity @@ -138,12 +139,13 @@ def auto_resolve_project_issues(project_id, cutoff=None, chunk_size=1000, **kwar ) analytics.record( - "issue.auto_resolved", - project_id=project.id, - organization_id=project.organization_id, - group_id=group.id, - issue_type=group.issue_type.slug, - issue_category=group.issue_category.name.lower(), + IssueAutoResolvedEvent( + project_id=project.id, + organization_id=project.organization_id, + group_id=group.id, + issue_type=group.issue_type.slug, + issue_category=group.issue_category.name.lower(), + ) ) # auto-resolve is a kind of resolve and this signal makes # sure all things that need to happen after resolve are triggered