Skip to content

Commit 618bb0c

Browse files
authored
feat:issueless events. Prepare data structures for issueless events (#13822)
This PR prepares the ground for skipping issue creation if the event has no fingerprint by removing some assumption that the group should always exists.
1 parent fe9828a commit 618bb0c

File tree

14 files changed

+158
-50
lines changed

14 files changed

+158
-50
lines changed

src/sentry/api/bases/event.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from __future__ import absolute_import
2+
3+
from sentry.api.bases.project import ProjectPermission
4+
5+
6+
class EventPermission(ProjectPermission):
7+
scope_map = {
8+
'GET': ['event:read', 'event:write', 'event:admin'],
9+
'POST': ['event:write', 'event:admin'],
10+
'PUT': ['event:write', 'event:admin'],
11+
'DELETE': ['event:admin'],
12+
}
13+
14+
def has_object_permission(self, request, view, event):
15+
return super(EventPermission, self).has_object_permission(
16+
request, view, event.project)

src/sentry/api/endpoints/event_details.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
from rest_framework.response import Response
44

55
from sentry.api.base import Endpoint
6-
from sentry.api.bases.group import GroupPermission
6+
from sentry.api.bases.event import EventPermission
77
from sentry.api.exceptions import ResourceDoesNotExist
88
from sentry.api.serializers import DetailedEventSerializer, serialize
99
from sentry.models import Event
1010

1111

1212
class EventDetailsEndpoint(Endpoint):
13-
permission_classes = (GroupPermission, )
13+
permission_classes = (EventPermission, )
1414

1515
def get(self, request, event_id):
1616
"""
@@ -27,7 +27,7 @@ def get(self, request, event_id):
2727
if event is None:
2828
raise ResourceDoesNotExist
2929

30-
self.check_object_permissions(request, event.group)
30+
self.check_object_permissions(request, event)
3131

3232
Event.objects.bind_nodes([event], 'data')
3333

src/sentry/api/serializers/models/event.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ def serialize(self, obj, attrs, user):
247247

248248
d = {
249249
'id': six.text_type(obj.id),
250-
'groupID': six.text_type(obj.group_id),
250+
'groupID': six.text_type(obj.group_id) if obj.group_id else None,
251251
'eventID': six.text_type(obj.event_id),
252252
'projectID': six.text_type(obj.project_id),
253253
'size': obj.size,
@@ -359,7 +359,7 @@ def serialize(self, obj, attrs, user):
359359
return {
360360
'id': six.text_type(obj.id),
361361
'event.type': six.text_type(obj.type),
362-
'groupID': six.text_type(obj.group_id),
362+
'groupID': six.text_type(obj.group_id) if obj.group_id else None,
363363
'eventID': six.text_type(obj.event_id),
364364
'projectID': six.text_type(obj.project_id),
365365
# XXX for 'message' this doesn't do the proper resolution of logentry

src/sentry/event_manager.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,7 @@ def save(self, project_id, raw=False, assume_normalized=False):
725725
extra={
726726
'event_uuid': event_id,
727727
'project_id': project.id,
728-
'group_id': group.id,
728+
'group_id': group.id if group else None,
729729
'model': EventMapping.__name__,
730730
}
731731
)
@@ -833,7 +833,7 @@ def save(self, project_id, raw=False, assume_normalized=False):
833833
extra={
834834
'event_uuid': event_id,
835835
'project_id': project.id,
836-
'group_id': group.id,
836+
'group_id': group.id if group else None,
837837
'model': Event.__name__,
838838
}
839839
)
@@ -842,7 +842,7 @@ def save(self, project_id, raw=False, assume_normalized=False):
842842
tagstore.delay_index_event_tags(
843843
organization_id=project.organization_id,
844844
project_id=project.id,
845-
group_id=group.id,
845+
group_id=group.id if group else None,
846846
environment_id=environment.id,
847847
event_id=event.id,
848848
tags=event.tags,
@@ -885,7 +885,8 @@ def save(self, project_id, raw=False, assume_normalized=False):
885885
if not raw:
886886
if not project.first_event:
887887
project.update(first_event=date)
888-
first_event_received.send_robust(project=project, group=group, sender=Project)
888+
first_event_received.send_robust(
889+
project=project, event=event, sender=Project)
889890

890891
eventstream.insert(
891892
group=group,

src/sentry/models/event.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ def generate_node_id(cls, project_id, event_id):
8989
@property
9090
def group(self):
9191
from sentry.models import Group
92+
if not self.group_id:
93+
return None
9294
if not hasattr(self, '_group_cache'):
9395
self._group_cache = Group.objects.get(id=self.group_id)
9496
return self._group_cache
@@ -223,7 +225,9 @@ def title(self):
223225
@property
224226
def culprit(self):
225227
# For a while events did not save the culprit
226-
return self.data.get('culprit') or self.group.culprit
228+
if self.group_id:
229+
return self.data.get('culprit') or self.group.culprit
230+
return self.data.get('culprit')
227231

228232
@property
229233
def location(self):
@@ -353,7 +357,7 @@ def as_dict(self):
353357

354358
# for a long time culprit was not persisted. In those cases put
355359
# the culprit in from the group.
356-
if data.get('culprit') is None:
360+
if data.get('culprit') is None and self.group_id:
357361
data['culprit'] = self.group.culprit
358362

359363
# Override title and location with dynamically generated data
@@ -370,12 +374,18 @@ def as_dict(self):
370374
def level(self):
371375
# we might want to move to this:
372376
# return LOG_LEVELS_MAP.get(self.get_level_display()) or self.group.level
373-
return self.group.level
377+
if self.group:
378+
return self.group.level
379+
else:
380+
return None
374381

375382
def get_level_display(self):
376383
# we might want to move to this:
377384
# return self.get_tag('level') or self.group.get_level_display()
378-
return self.group.get_level_display()
385+
if self.group:
386+
return self.group.get_level_display()
387+
else:
388+
return None
379389

380390
# deprecated accessors
381391

@@ -630,7 +640,7 @@ def next_event_id(self, environments=None):
630640
conditions=conditions,
631641
filter_keys={
632642
'project_id': [self.project_id],
633-
'issue': [self.group_id],
643+
'issue': [self.group_id] if self.group_id else [],
634644
},
635645
orderby=['timestamp', 'event_id'],
636646
limit=1,
@@ -660,7 +670,7 @@ def prev_event_id(self, environments=None):
660670
conditions=conditions,
661671
filter_keys={
662672
'project_id': [self.project_id],
663-
'issue': [self.group_id],
673+
'issue': [self.group_id] if self.group_id else [],
664674
},
665675
orderby=['-timestamp', '-event_id'],
666676
limit=1,
@@ -778,7 +788,7 @@ def __getitem__(self, name):
778788
return self.event.project.get_full_name()
779789
elif name == 'projectID':
780790
return self.event.project.slug
781-
elif name == 'shortID':
791+
elif name == 'shortID' and self.event.group_id:
782792
return self.event.group.qualified_short_id
783793
elif name == 'orgID':
784794
return self.event.organization.slug

src/sentry/receivers/features.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050

5151
# First Event
5252
@first_event_received.connect(weak=False)
53-
def record_first_event(project, group, **kwargs):
53+
def record_first_event(project, **kwargs):
5454
FeatureAdoption.objects.record(
5555
organization_id=project.organization_id, feature_slug="first_event", complete=True
5656
)

src/sentry/receivers/onboarding.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def record_raven_installed(project, user, **kwargs):
9393

9494

9595
@first_event_received.connect(weak=False)
96-
def record_first_event(project, group, **kwargs):
96+
def record_first_event(project, event, **kwargs):
9797
"""
9898
Requires up to 2 database calls, but should only run with the first event in
9999
any project, so performance should not be a huge bottleneck.
@@ -111,7 +111,7 @@ def record_first_event(project, group, **kwargs):
111111
'project_id': project.id,
112112
'date_completed': project.first_event,
113113
'data': {
114-
'platform': group.platform
114+
'platform': event.platform
115115
},
116116
}
117117
)
@@ -124,7 +124,7 @@ def record_first_event(project, group, **kwargs):
124124
user_id=user.id,
125125
organization_id=project.organization_id,
126126
project_id=project.id,
127-
platform=group.platform,
127+
platform=event.platform,
128128
)
129129
return
130130

@@ -138,8 +138,8 @@ def record_first_event(project, group, **kwargs):
138138

139139
# Only counts if it's a new project and platform
140140
if oot.project_id != project.id and oot.data.get(
141-
'platform', group.platform
142-
) != group.platform:
141+
'platform', event.platform
142+
) != event.platform:
143143
rows_affected, created = OrganizationOnboardingTask.objects.create_or_update(
144144
organization_id=project.organization_id,
145145
task=OnboardingTask.SECOND_PLATFORM,
@@ -149,7 +149,7 @@ def record_first_event(project, group, **kwargs):
149149
'project_id': project.id,
150150
'date_completed': project.first_event,
151151
'data': {
152-
'platform': group.platform
152+
'platform': event.platform
153153
},
154154
}
155155
)
@@ -159,7 +159,7 @@ def record_first_event(project, group, **kwargs):
159159
user_id=user.id,
160160
organization_id=project.organization_id,
161161
project_id=project.id,
162-
platform=group.platform,
162+
platform=event.platform,
163163
)
164164

165165

src/sentry/signals.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def send_robust(self, sender, **named):
6666
# Organization Onboarding Signals
6767
project_created = BetterSignal(providing_args=["project", "user"])
6868
first_event_pending = BetterSignal(providing_args=["project", "user"])
69-
first_event_received = BetterSignal(providing_args=["project", "group"])
69+
first_event_received = BetterSignal(providing_args=["project", "event"])
7070
member_invited = BetterSignal(providing_args=["member", "user"])
7171
member_joined = BetterSignal(providing_args=["member", "organization"])
7272
issue_tracker_used = BetterSignal(providing_args=["plugin", "project", "user"])

src/sentry/similarity/features.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ def record(self, events):
102102

103103
items = []
104104
for event in events:
105+
# TODO: how we index events?
106+
if not event.group_id:
107+
continue
105108
for label, features in self.extract(event).items():
106109
if scope is None:
107110
scope = self.__get_scope(event.project)

src/sentry/testutils/factories.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -447,11 +447,11 @@ def create_useremail(user, email, **kwargs):
447447
return useremail
448448

449449
@staticmethod
450-
def create_event(group, event_id=None, normalize=True, **kwargs):
450+
def create_event(group=None, project=None, event_id=None, normalize=True, **kwargs):
451451
# XXX: Do not use this method for new tests! Prefer `store_event`.
452452
if event_id is None:
453453
event_id = uuid4().hex
454-
kwargs.setdefault('project', group.project)
454+
kwargs.setdefault('project', project if project else group.project)
455455
kwargs.setdefault('data', copy.deepcopy(DEFAULT_EVENT_DATA))
456456
kwargs.setdefault('platform', kwargs['data'].get('platform', 'python'))
457457
kwargs.setdefault('message', kwargs['data'].get('message', 'message'))
@@ -497,11 +497,12 @@ def create_event(group, event_id=None, normalize=True, **kwargs):
497497
)
498498

499499
event = Event(event_id=event_id, group=group, **kwargs)
500-
EventMapping.objects.create(
501-
project_id=event.project.id,
502-
event_id=event_id,
503-
group=group,
504-
)
500+
if group:
501+
EventMapping.objects.create(
502+
project_id=event.project.id,
503+
event_id=event_id,
504+
group=group,
505+
)
505506
# emulate EventManager refs
506507
event.data.bind_ref(event)
507508
event.save()

0 commit comments

Comments
 (0)