def test_get_group_backfill_attributes(self): now = datetime.utcnow().replace(microsecond=0, tzinfo=timezone.utc) assert get_group_backfill_attributes( get_caches(), Group( active_at=now, first_seen=now, last_seen=now, platform="javascript", message="Hello from JavaScript", level=logging.INFO, score=Group.calculate_score(3, now), logger="javascript", times_seen=1, first_release=None, culprit="", data={ "type": "default", "last_received": to_timestamp(now), "metadata": {} }, ), [ self.store_event( data={ "platform": "python", "message": "Hello from Python", "timestamp": iso_format(now - timedelta(hours=1)), "type": "default", "level": "debug", "tags": { "logger": "java" }, }, project_id=self.project.id, ), self.store_event( data={ "platform": "java", "message": "Hello from Java", "timestamp": iso_format(now - timedelta(hours=2)), "type": "default", "level": "debug", "tags": { "logger": "java" }, }, project_id=self.project.id, ), ], ) == { "active_at": now - timedelta(hours=2), "first_seen": now - timedelta(hours=2), "platform": "java", "score": Group.calculate_score(3, now), "logger": "java", "times_seen": 3, "first_release": None, }
def test_notify_users_does_email(self, _send_mail): project = Project(id=1, name="Project Name") group = Group() group.first_seen = datetime.datetime.now() group.last_seen = group.first_seen group.project = project group.id = 2 event = Event() event.group = group event.message = "hello world" event.logger = "root" event.project = project event.date = group.last_seen with self.Settings(SENTRY_URL_PREFIX="http://example.com"): p = MailProcessor(send_to=["*****@*****.**"]) p.notify_users(group, event) _send_mail.assert_called_once() args, kwargs = _send_mail.call_args self.assertEquals(kwargs.get("fail_silently"), False) self.assertEquals(kwargs.get("project"), project) self.assertEquals(kwargs.get("subject"), u"[Project Name] ERROR: hello world")
def build_context(group: Group) -> Mapping[str, Any]: result, stats_24hr = get_serialized_and_stats(group, "24h") _, stats_14d = get_serialized_and_stats(group, "14d") first_release = group.get_first_release() if first_release is not None: last_release = group.get_last_release() else: last_release = None first_release_url = None if first_release: first_release_url = get_release_url(group, first_release) last_release_url = None if last_release: last_release_url = get_release_url(group, last_release) group_url = group.get_absolute_url( params={"referrer": "sentry-issues-glance"}) return { "type": result.get("metadata", {}).get("type", "Unknown Error"), "title": group.title, "title_url": group_url, "first_seen": result["firstSeen"], "last_seen": result["lastSeen"], "first_release": first_release, "first_release_url": first_release_url, "last_release": last_release, "last_release_url": last_release_url, "stats_24hr": stats_24hr, "stats_14d": stats_14d, }
def test_notify_users_does_email(self, _send_mail): project = Project(id=1, name='Project Name') group = Group() group.first_seen = timezone.now() group.last_seen = group.first_seen group.project = project group.id = 2 event = Event() event.group = group event.message = 'hello world' event.logger = 'root' event.project = project event.date = group.last_seen with self.Settings(SENTRY_URL_PREFIX='http://example.com'): p = MailProcessor(send_to=['*****@*****.**']) p.notify_users(group, event) _send_mail.assert_called_once() args, kwargs = _send_mail.call_args self.assertEquals(kwargs.get('fail_silently'), False) self.assertEquals(kwargs.get('project'), project) self.assertEquals(kwargs.get('subject'), u"[Project Name] ERROR: hello world")
def make_group_generator(random, project): epoch = to_timestamp(datetime(2016, 6, 1, 0, 0, 0, tzinfo=timezone.utc)) for id in itertools.count(1): first_seen = epoch + random.randint(0, 60 * 60 * 24 * 30) last_seen = random.randint(first_seen, first_seen + (60 * 60 * 24 * 30)) culprit = make_culprit(random) level = random.choice(LOG_LEVELS.keys()) message = make_message(random) group = Group( id=id, project=project, culprit=culprit, level=level, message=message, first_seen=to_datetime(first_seen), last_seen=to_datetime(last_seen), status=random.choice((GroupStatus.UNRESOLVED, GroupStatus.RESOLVED, )), data={ 'type': 'default', 'metadata': { 'title': message, } } ) if random.random() < 0.8: group.data = make_group_metadata(random, group) yield group
def make_group_generator(random, project): epoch = to_timestamp(datetime(2016, 6, 1, 0, 0, 0, tzinfo=timezone.utc)) for id in itertools.count(1): first_seen = epoch + random.randint(0, 60 * 60 * 24 * 30) last_seen = random.randint(first_seen, first_seen + (60 * 60 * 24 * 30)) culprit = make_culprit(random) level = random.choice(LOG_LEVELS.keys()) message = make_message(random) group = Group( id=id, project=project, culprit=culprit, level=level, message=message, first_seen=to_datetime(first_seen), last_seen=to_datetime(last_seen), status=random.choice((GroupStatus.UNRESOLVED, GroupStatus.RESOLVED)), data={"type": "default", "metadata": {"title": message}}, ) if random.random() < 0.8: group.data = make_group_metadata(random, group) yield group
def test_get_group_backfill_attributes(self): now = datetime(2017, 5, 3, 6, 6, 6, tzinfo=pytz.utc) assert get_group_backfill_attributes( get_caches(), Group( active_at=now, first_seen=now, last_seen=now, platform='javascript', message='Hello from JavaScript', level=logging.INFO, score=Group.calculate_score(3, now), logger='javascript', times_seen=1, first_release=None, culprit='', data={ 'type': 'default', 'last_received': to_timestamp(now), 'metadata': {}, }, ), [ Event( platform='python', message='Hello from Python', datetime=now - timedelta(hours=1), data={ 'type': 'default', 'metadata': {}, 'tags': [ ['level', 'error'], ['logger', 'python'], ], }, ), Event( platform='java', message='Hello from Java', datetime=now - timedelta(hours=2), data={ 'type': 'default', 'metadata': {}, 'tags': [ ['level', 'debug'], ['logger', 'java'], ], }, ), ], ) == { 'active_at': now - timedelta(hours=2), 'first_seen': now - timedelta(hours=2), 'platform': 'java', 'score': Group.calculate_score(3, now), 'logger': 'java', 'times_seen': 3, 'first_release': None, }
def build_actions( group: Group, project: Project, text: str, color: str, actions: Sequence[MessageAction] | None = None, identity: Identity | None = None, ) -> tuple[Sequence[MessageAction], str, str]: """Having actions means a button will be shown on the Slack message e.g. ignore, resolve, assign.""" if actions: text += get_action_text(text, actions, identity) return [], text, "_actioned_issue" ignore_button = MessageAction( name="status", label="Ignore", value="ignored", ) resolve_button = MessageAction( name="resolve_dialog", label="Resolve...", value="resolve_dialog", ) status = group.get_status() if not has_releases(project): resolve_button = MessageAction( name="status", label="Resolve", value="resolved", ) if status == GroupStatus.RESOLVED: resolve_button = MessageAction( name="status", label="Unresolve", value="unresolved", ) if status == GroupStatus.IGNORED: ignore_button = MessageAction( name="status", label="Stop Ignoring", value="unresolved", ) assignee = group.get_assignee() assign_button = MessageAction( name="assign", label="Select Assignee...", type="select", selected_options=format_actor_options([assignee]) if assignee else [], option_groups=get_option_groups(group), ) return [resolve_button, ignore_button, assign_button], text, color
def new_note(request): org = Organization( id=1, slug='example', name='Example', ) team = Team( id=1, slug='example', name='Example', organization=org, ) project = Project( id=1, slug='example', name='Example', team=team, organization=org, ) group = Group( id=1, project=project, message='This is an example event.', ) event = Event( id=1, project=project, group=group, message=group.message, data=load_data('python'), ) note = Activity( group=event.group, event=event, project=event.project, type=Activity.NOTE, user=request.user, data={'text': 'This is an example note!'}, ) preview = MailPreview( html_template='sentry/emails/activity/note.html', text_template='sentry/emails/activity/note.txt', context={ 'data': note.data, 'author': note.user, 'date': note.datetime, 'group': group, 'link': group.get_absolute_url(), }, ) return render_to_response('sentry/debug/mail/preview.html', { 'preview': preview, })
def assigned(request): org = Organization( id=1, slug='example', name='Example', ) team = Team( id=1, slug='example', name='Example', organization=org, ) project = Project( id=1, slug='example', name='Example', team=team, organization=org, ) group = Group( id=1, project=project, message='This is an example event.', ) event = Event( id=1, project=project, group=group, message=group.message, data=load_data('python'), ) assigned = Activity( group=event.group, project=event.project, type=Activity.ASSIGNED, user=request.user, data={ 'text': 'This is an example note!', 'assignee': '*****@*****.**' }, ) return MailPreview( html_template='sentry/emails/activity/assigned.html', text_template='sentry/emails/activity/assigned.txt', context={ 'data': assigned.data, 'author': assigned.user, 'date': assigned.datetime, 'group': group, 'link': group.get_absolute_url(), }, ).render()
def test_get_group_backfill_attributes(self): now = datetime(2017, 5, 3, 6, 6, 6, tzinfo=pytz.utc) assert get_group_backfill_attributes( get_caches(), Group( active_at=now, first_seen=now, last_seen=now, platform="javascript", message="Hello from JavaScript", level=logging.INFO, score=Group.calculate_score(3, now), logger="javascript", times_seen=1, first_release=None, culprit="", data={ "type": "default", "last_received": to_timestamp(now), "metadata": {} }, ), [ Event( platform="python", message="Hello from Python", datetime=now - timedelta(hours=1), data={ "type": "default", "metadata": {}, "tags": [["level", "error"], ["logger", "python"]], }, ), Event( platform="java", message="Hello from Java", datetime=now - timedelta(hours=2), data={ "type": "default", "metadata": {}, "tags": [["level", "debug"], ["logger", "java"]], }, ), ], ) == { "active_at": now - timedelta(hours=2), "first_seen": now - timedelta(hours=2), "platform": "java", "score": Group.calculate_score(3, now), "logger": "java", "times_seen": 3, "first_release": None, }
def assigned(request): org = Organization( id=1, slug='example', name='Example', ) team = Team( id=1, slug='example', name='Example', organization=org, ) project = Project( id=1, slug='example', name='Example', team=team, organization=org, ) group = Group( id=1, project=project, message='This is an example event.', ) event = Event( id=1, project=project, group=group, message=group.message, data=load_data('python'), ) assigned = Activity( group=event.group, event=event, project=event.project, type=Activity.ASSIGNED, user=request.user, data={'text': 'This is an example note!'}, ) return MailPreview( html_template='sentry/emails/activity/assigned.html', text_template='sentry/emails/activity/assigned.txt', context={ 'data': assigned.data, 'author': assigned.user, 'date': assigned.datetime, 'group': group, 'link': group.get_absolute_url(), }, ).render()
def test_notify_users_renders_interfaces(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, ) stacktrace = Mock(spec=Stacktrace) stacktrace.to_email_html.return_value = 'foo bar' stacktrace.get_title.return_value = 'Stacktrace' event = Event() event.group = group event.project = self.project event.message = 'hello world' event.logger = 'root' event.site = None event.interfaces = {'sentry.interfaces.Stacktrace': stacktrace} with self.settings(SENTRY_URL_PREFIX='http://example.com'): self.plugin.notify_users(group, event) stacktrace.get_title.assert_called_once_with() stacktrace.to_email_html.assert_called_once_with(event)
def test_notify_users_does_email(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, ) event = Event( group=group, message='hello world', logger='root', project=self.project, datetime=group.last_seen, ) with self.Settings(SENTRY_URL_PREFIX='http://example.com'): self.plugin.notify_users(group, event) _send_mail.assert_called_once() args, kwargs = _send_mail.call_args self.assertEquals(kwargs.get('fail_silently'), False) self.assertEquals(kwargs.get('project'), self.project) assert kwargs.get('subject') == u"[{0}] ERROR: hello world".format( self.project.name)
def test_notify_users_renders_interfaces_with_utf8(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, ) stacktrace = Mock(spec=Stacktrace) stacktrace.to_string.return_value = u'רונית מגן' stacktrace.get_title.return_value = 'Stacktrace' event = Event() event.group = group event.message = 'hello world' event.logger = 'root' event.site = None event.interfaces = {'sentry.interfaces.Stacktrace': stacktrace} with self.Settings(SENTRY_URL_PREFIX='http://example.com'): p = MailProcessor(send_to=['*****@*****.**']) p.notify_users(group, event) stacktrace.get_title.assert_called_once_with() stacktrace.to_string.assert_called_once_with(event)
def test_notify_users_does_email(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, message='hello world', logger='root', short_id=2, ) event = Event( group=group, message=group.message, project=self.project, datetime=group.last_seen, data={'tags': [ ('level', 'error'), ]}, ) notification = Notification(event=event) with self.options({'system.url-prefix': 'http://example.com'}): self.plugin.notify(notification) assert _send_mail.call_count is 1 args, kwargs = _send_mail.call_args self.assertEquals(kwargs.get('project'), self.project) self.assertEquals(kwargs.get('reference'), group) assert kwargs.get('subject') == u'BAR-2 - hello world'
def get(self, request, share_id): """ Retrieve an aggregate Return details on an individual aggregate specified by it's shared ID. {method} {path} Note: This is not the equivilant of what you'd receive with the standard group details endpoint. Data is more restrictive and designed specifically for sharing. """ try: group = Group.from_share_id(share_id) except Group.DoesNotExist: raise ResourceDoesNotExist event = group.get_latest_event() context = serialize(group, request.user, SharedGroupSerializer()) context['latestEvent'] = serialize(event, request.user, SharedEventSerializer()) # TODO(dcramer): use specific serializer for public group and embed # event details as part of api response return Response(context)
def test_notify_users_renders_interfaces_with_utf8_fix_issue_422( self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, ) stacktrace = Mock(spec=Stacktrace) stacktrace.to_string.return_value = u'רונית מגן' stacktrace.get_title.return_value = 'Stacktrace' event = Event() event.group = group event.message = 'Soubor ji\xc5\xbe existuje' event.logger = 'root' event.site = None event.interfaces = {'sentry.interfaces.Stacktrace': stacktrace} with self.Settings(SENTRY_URL_PREFIX='http://example.com'): self.plugin.notify_users(group, event) stacktrace.get_title.assert_called_once_with() stacktrace.to_string.assert_called_once_with(event)
def test_notify_users_renders_interfaces_with_utf8_fix_issue_422(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, ) stacktrace = Mock(spec=Stacktrace) stacktrace.to_email_html.return_value = u'רונית מגן' stacktrace.get_title.return_value = 'Stacktrace' event = Event() event.group = group event.project = self.project event.message = 'Soubor ji\xc5\xbe existuje' event.interfaces = {'sentry.interfaces.Stacktrace': stacktrace} notification = Notification(event=event) with self.options({'system.url-prefix': 'http://example.com'}): self.plugin.notify(notification) stacktrace.get_title.assert_called_once_with() stacktrace.to_email_html.assert_called_once_with(event)
def test_multiline_error(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, message='hello world\nfoo bar', logger='root', ) event = Event( group=group, message=group.message, project=self.project, datetime=group.last_seen, ) notification = Notification(event=event) with self.settings(SENTRY_URL_PREFIX='http://example.com'): self.plugin.notify(notification) _send_mail.assert_called_once() args, kwargs = _send_mail.call_args assert kwargs.get('subject') == u"[{0} {1}] ERROR: hello world".format( self.team.name, self.project.name)
def test_notify_users_renders_interfaces_with_utf8(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, ) stacktrace = Mock(spec=Stacktrace) stacktrace.to_email_html.return_value = u'רונית מגן' stacktrace.get_title.return_value = 'Stacktrace' event = Event() event.group = group event.project = self.project event.message = 'hello world' event.interfaces = {'sentry.interfaces.Stacktrace': stacktrace} notification = Notification(event=event) with self.settings(SENTRY_URL_PREFIX='http://example.com'): self.plugin.notify(notification) stacktrace.get_title.assert_called_once_with() stacktrace.to_email_html.assert_called_once_with(event)
def test_multiline_error(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, message='hello world\nfoo bar', logger='root', ) event = Event( group=group, message=group.message, project=self.project, datetime=group.last_seen, data={ 'tags': [ ('level', 'error'), ] }, ) notification = Notification(event=event) with self.options({'system.url-prefix': 'http://example.com'}): self.plugin.notify(notification) assert _send_mail.call_count is 1 args, kwargs = _send_mail.call_args assert kwargs.get('subject') == u"[{0} {1}] ERROR: hello world".format( self.team.name, self.project.name)
def test_notify_users_does_email(self, _send_mail): group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, message='hello world', logger='root', ) event = Event( group=group, message=group.message, project=self.project, datetime=group.last_seen, ) notification = Notification(event=event) with self.options({'system.url-prefix': 'http://example.com'}): self.plugin.notify(notification) assert _send_mail.call_count is 1 args, kwargs = _send_mail.call_args self.assertEquals(kwargs.get('project'), self.project) self.assertEquals(kwargs.get('group'), group) assert kwargs.get('subject') == u"[{0} {1}] ERROR: hello world".format( self.team.name, self.project.name)
def get(self, request, share_id): """ Retrieve an aggregate Return details on an individual aggregate specified by it's shared ID. {method} {path} Note: This is not the equivilant of what you'd receive with the standard group details endpoint. Data is more restrictive and designed specifically for sharing. """ try: group = Group.from_share_id(share_id) except Group.DoesNotExist: raise ResourceDoesNotExist if group.organization.flags.disable_shared_issues: raise ResourceDoesNotExist event = group.get_latest_event() context = serialize(group, request.user, SharedGroupSerializer()) context['latestEvent'] = serialize(event, request.user, SharedEventSerializer()) # TODO(dcramer): use specific serializer for public group and embed # event details as part of api response return Response(context)
def get(self, request, share_id): """ Retrieve an aggregate Return details on an individual aggregate specified by it's shared ID. {method} {path} Note: This is not the equivilant of what you'd receive with the standard group details endpoint. Data is more restrictive and designed specifically for sharing. """ try: group = Group.from_share_id(share_id) except Group.DoesNotExist: raise ResourceDoesNotExist if group.organization.flags.disable_shared_issues: raise ResourceDoesNotExist event = group.get_latest_event() context = serialize( group, request.user, SharedGroupSerializer( environment_id_func=self._get_environment_id_func( request, group.project.organization_id))) # TODO(dcramer): move latestEvent/project into SharedGroupSerializer context['latestEvent'] = serialize(event, request.user, SharedEventSerializer()) context['project'] = serialize(group.project, request.user, SharedProjectSerializer()) return Response(context)
def new_event(request): org = Organization( id=1, slug='example', name='Example', ) team = Team( id=1, slug='example', name='Example', organization=org, ) project = Project( id=1, slug='example', name='Example', team=team, organization=org, ) group = Group( id=1, project=project, message='This is an example event.', level=logging.ERROR, ) event = Event( id=1, project=project, group=group, message=group.message, data=load_data('python'), ) rule = Rule(label="An example rule") interface_list = [] for interface in event.interfaces.itervalues(): body = interface.to_email_html(event) if not body: continue interface_list.append((interface.get_title(), mark_safe(body))) preview = MailPreview( html_template='sentry/emails/error.html', text_template='sentry/emails/error.html', context={ 'rule': rule, 'group': group, 'event': event, 'link': 'http://example.com/link', 'interfaces': interface_list, 'tags': event.get_tags(), 'project_label': project.name, }, ) return render_to_response('sentry/debug/mail/preview.html', { 'preview': preview, })
def test_multiline_error(self, _send_mail): event_manager = EventManager({"message": "hello world\nfoo bar", "level": "error"}) event_manager.normalize() event_data = event_manager.get_data() event_type = event_manager.get_event_type() event_data["type"] = event_type.key event_data["metadata"] = event_type.get_metadata(event_data) group = Group( id=2, first_seen=timezone.now(), last_seen=timezone.now(), project=self.project, message=event_manager.get_search_message(), logger="root", short_id=2, data={"type": event_type.key, "metadata": event_type.get_metadata(event_data)}, ) event = Event( group=group, message=group.message, project=self.project, datetime=group.last_seen, data=event_data, ) notification = Notification(event=event) with self.options({"system.url-prefix": "http://example.com"}): self.plugin.notify(notification) assert _send_mail.call_count is 1 args, kwargs = _send_mail.call_args assert kwargs.get("subject") == u"BAR-2 - hello world"
def test_process_does_save_call_with_results(self, process): group = Group(project=Project(id=1)) columns = {'times_seen': 1} filters = {'pk': group.pk} self.buffer._tnt.insert(self.sentry_space, ('foo', 2, 0L)) self.buffer.process(Group, columns, filters) process.assert_called_once_with(Group, {'times_seen': 2}, filters, None)
def get_title_link( group: Group, event: Optional[Event], link_to_event: bool, issue_details: bool, notification: Optional[BaseNotification], ) -> Any: if event and link_to_event: return group.get_absolute_url(params={"referrer": "slack"}, event_id=event.event_id) if issue_details: referrer = re.sub("Notification$", "Slack", notification.__class__.__name__) return group.get_absolute_url(params={"referrer": referrer}) return group.get_absolute_url(params={"referrer": "slack"})
def test_process_does_clear_buffer(self, process): group = Group(project=Project(id=1)) columns = {'times_seen': 1} filters = {'pk': group.pk} self.buffer._tnt.insert(self.sentry_space, ('foo', 2, 0L)) self.buffer.process(Group, columns, filters) response = self.buffer._tnt.select(self.sentry_space, ['foo']) self.assertEquals(int(response[0][1]), 0)
def test_get_group_creation_attributes(self): now = datetime.utcnow().replace(microsecond=0, tzinfo=timezone.utc) e1 = self.store_event( data={ "fingerprint": ["group1"], "platform": "javascript", "message": "Hello from JavaScript", "type": "default", "level": "info", "tags": {"logger": "javascript"}, "timestamp": iso_format(now), }, project_id=self.project.id, ) e2 = self.store_event( data={ "fingerprint": ["group1"], "platform": "python", "message": "Hello from Python", "type": "default", "level": "error", "tags": {"logger": "python"}, "timestamp": iso_format(now), }, project_id=self.project.id, ) e3 = self.store_event( data={ "fingerprint": ["group1"], "platform": "java", "message": "Hello from Java", "type": "default", "level": "debug", "tags": {"logger": "java"}, "timestamp": iso_format(now), }, project_id=self.project.id, ) events = [e1, e2, e3] assert get_group_creation_attributes(get_caches(), events) == { "active_at": now, "first_seen": now, "last_seen": now, "platform": "java", "message": "Hello from JavaScript", "level": logging.INFO, "score": Group.calculate_score(3, now), "logger": "java", "times_seen": 3, "first_release": None, "culprit": "", "data": { "type": "default", "last_received": e1.data["received"], "metadata": {"title": "Hello from JavaScript"}, }, }
def create_event(data, group_id=123): mgr = EventManager(data=data, grouping_config=get_default_grouping_config_dict()) mgr.normalize() data = mgr.get_data() evt = eventstore.create_event(data=data) evt.project = project = Project(id=123) evt.group = Group(id=group_id, project=project) return evt
def get_assignee_string(group: Group) -> Optional[str]: """Get a string representation of the group's assignee.""" assignee = group.get_assignee() if isinstance(assignee, User): return assignee.email if isinstance(assignee, Team): return f"#{assignee.slug}" return None
def test_gracefully_handles_commit_race_condition(self, retry, get): does_not_exist = Group.DoesNotExist() # Fail once, then transaction commits, and next retry succeeds get.side_effect = [does_not_exist, None] with self.tasks(): self.create_group(project=self.project) retry.assert_called_with(exc=does_not_exist)
def get_title_link( group: Group, event: Optional[Event], link_to_event: bool, issue_details: bool, notification: Optional[BaseNotification], ) -> str: if event and link_to_event: url = group.get_absolute_url(params={"referrer": "slack"}, event_id=event.event_id) elif issue_details: referrer = re.sub("Notification$", "Slack", notification.__class__.__name__) url = group.get_absolute_url(params={"referrer": referrer}) else: url = group.get_absolute_url(params={"referrer": "slack"}) # Explicitly typing to satisfy mypy. url_str: str = url return url_str
def make_group_generator(random, project): epoch = to_timestamp(datetime(2016, 6, 1, 0, 0, 0, tzinfo=timezone.utc)) for id in itertools.count(1): first_seen = epoch + random.randint(0, 60 * 60 * 24 * 30) last_seen = random.randint(first_seen, first_seen + (60 * 60 * 24 * 30)) group = Group( id=id, project=project, culprit=make_culprit(random), level=random.choice(LOG_LEVELS.keys()), message=make_message(random), first_seen=to_datetime(first_seen), last_seen=to_datetime(last_seen), ) if random.random() < 0.8: group.data = make_group_metadata(random, group) yield group
def test_notify_users_renders_interfaces(self, _send_mail): group = Group() group.first_seen = datetime.datetime.now() group.last_seen = group.first_seen group.id = 2 group.project_id = 1 stacktrace = Mock(spec=Stacktrace) stacktrace.to_string.return_value = "foo bar" stacktrace.get_title.return_value = "Stacktrace" event = Event() event.group = group event.message = "hello world" event.logger = "root" event.site = None event.interfaces = {"sentry.interfaces.Stacktrace": stacktrace} with self.Settings(SENTRY_URL_PREFIX="http://example.com"): p = MailProcessor(send_to=["*****@*****.**"]) p.notify_users(group, event) stacktrace.get_title.assert_called_once_with() stacktrace.to_string.assert_called_once_with(event)
def test_notify_users_renders_interfaces_with_utf8(self, _send_mail): group = Group() group.first_seen = timezone.now() group.last_seen = group.first_seen group.id = 2 group.project_id = 1 stacktrace = Mock(spec=Stacktrace) stacktrace.to_string.return_value = u'רונית מגן' stacktrace.get_title.return_value = 'Stacktrace' event = Event() event.group = group event.message = 'hello world' event.logger = 'root' event.site = None event.interfaces = {'sentry.interfaces.Stacktrace': stacktrace} with self.Settings(SENTRY_URL_PREFIX='http://example.com'): p = MailProcessor(send_to=['*****@*****.**']) p.notify_users(group, event) stacktrace.get_title.assert_called_once_with() stacktrace.to_string.assert_called_once_with(event)
def get(self, request): """ Retrieve an aggregate Return details on an individual aggregate specified by query parameters. {method} {path}?shareId=mnIX """ share_id = request.GET.get('shareId') if share_id: try: group = Group.from_share_id(share_id) except Group.DoesNotExist: group = None else: group = None if not group: return Response({'detail': 'No groups found'}, status=404) return client.get('/groups/{}/'.format(group.id), request.user, request.auth)
'times_seen': lambda event: 0, } backfill_fields = { 'platform': lambda caches, data, event: event.platform, 'logger': lambda caches, data, event: event.get_tag('logger') or DEFAULT_LOGGER_NAME, 'first_seen': lambda caches, data, event: event.datetime, 'active_at': lambda caches, data, event: event.datetime, 'first_release': lambda caches, data, event: caches['Release']( caches['Project'](event.project_id).organization_id, event.get_tag('sentry:release'), ) if event.get_tag('sentry:release') else data.get('first_release', None), 'times_seen': lambda caches, data, event: data['times_seen'] + 1, 'score': lambda caches, data, event: Group.calculate_score( data['times_seen'] + 1, data['last_seen'], ), } def get_group_creation_attributes(caches, events): latest_event = events[0] return reduce( lambda data, event: merge_mappings([ data, {name: f(caches, data, event) for name, f in backfill_fields.items()}, ]), events, {name: f(latest_event) for name, f in initial_fields.items()}, )
def test_get_group_creation_attributes(self): now = datetime(2017, 5, 3, 6, 6, 6, tzinfo=pytz.utc) events = [ Event( platform='javascript', message='Hello from JavaScript', datetime=now, data={ 'type': 'default', 'metadata': {}, 'tags': [ ['level', 'info'], ['logger', 'javascript'], ], }, ), Event( platform='python', message='Hello from Python', datetime=now - timedelta(hours=1), data={ 'type': 'default', 'metadata': {}, 'tags': [ ['level', 'error'], ['logger', 'python'], ], }, ), Event( platform='java', message='Hello from Java', datetime=now - timedelta(hours=2), data={ 'type': 'default', 'metadata': {}, 'tags': [ ['level', 'debug'], ['logger', 'java'], ], }, ), ] assert get_group_creation_attributes( get_caches(), events, ) == { 'active_at': now - timedelta(hours=2), 'first_seen': now - timedelta(hours=2), 'last_seen': now, 'platform': 'java', 'message': 'Hello from JavaScript', 'level': logging.INFO, 'score': Group.calculate_score(3, now), 'logger': 'java', 'times_seen': 3, 'first_release': None, 'culprit': '', 'data': { 'type': 'default', 'last_received': to_timestamp(now), 'metadata': {}, }, }
def test_invalid_shared_id(self): with pytest.raises(Group.DoesNotExist): Group.from_share_id('adc7a5b902184ce3818046302e94f8ec')