def test_simple_notification(self):
        responses.add(
            'POST',
            'https://alert.victorops.com/integrations/generic/20131114/alert/secret-api-key/everyone',
            body=SUCCESS)
        self.plugin.set_option('api_key', 'secret-api-key', self.project)
        self.plugin.set_option('routing_key', 'everyone', self.project)

        group = self.create_group(message='Hello world', culprit='foo.bar')
        event = self.create_event(group=group,
                                  message='Hello world',
                                  tags={'level': 'warning'})

        rule = Rule.objects.create(project=self.project, label='my rule')

        notification = Notification(event=event, rule=rule)

        with self.options({'system.url-prefix': 'http://example.com'}):
            self.plugin.notify(notification)

        request = responses.calls[0].request
        payload = json.loads(request.body)
        assert {
            'message_type': 'WARNING',
            'entity_id': group.id,
            'entity_display_name': 'Hello world',
            'monitoring_tool': 'sentry',
            'state_message':
            'Stacktrace\n-----------\n\nStacktrace (most recent call last):\n\n  File "sentry/models/foo.py", line 29, in build_msg\n    string_max_length=self.string_max_length)\n\nMessage\n-----------\n\nHello world',
            'timestamp': int(event.datetime.strftime('%s')),
        } == payload
Exemple #2
0
    def rule_notify(self, event, futures):
        rules = []
        for future in futures:
            rules.append(future.rule)
            if not future.kwargs:
                continue
            raise NotImplementedError(
                'The default behavior for notification de-duplication does not support args'
            )

        project = event.group.project
        if hasattr(self, 'notify_digest') and digests.enabled(project):
            get_digest_option = lambda key: ProjectOption.objects.get_value(
                project,
                get_digest_option_key(self.get_conf_key(), key),
            )
            digest_key = unsplit_key(self, event.group.project)
            immediate_delivery = digests.add(
                digest_key,
                event_to_record(event, rules),
                increment_delay=get_digest_option('increment_delay'),
                maximum_delay=get_digest_option('maximum_delay'),
            )
            if immediate_delivery:
                deliver_digest.delay(digest_key)

        else:
            notification = Notification(event=event, rules=rules)
            self.notify(notification)
Exemple #3
0
    def test_notification_without_culprit(self):
        responses.add('POST', 'http://example.com/slack')
        self.plugin.set_option('webhook', 'http://example.com/slack', self.project)
        self.plugin.set_option('exclude_culprit', True, self.project)

        group = self.create_group(message='Hello world', culprit='foo.bar')
        event = self.create_event(group=group, message='Hello world', tags={'level': 'warning'})

        rule = Rule.objects.create(project=self.project, label='my rule')

        notification = Notification(event=event, rule=rule)

        with self.options({'system.url-prefix': 'http://example.com'}):
            self.plugin.notify(notification)

        request = responses.calls[0].request
        payload = json.loads(parse_qs(request.body)['payload'][0])
        assert payload == {
            'username': '******',
            'attachments': [
                {
                    'color': '#f18500',
                    'fields': [
                        {
                            'short': True,
                            'value': 'foo Bar',
                            'title': 'Project'
                        },
                    ],
                    'fallback': '[foo Bar] Hello world',
                    'title': 'Hello world',
                    'title_link': 'http://example.com/baz/bar/issues/1/',
                },
            ],
        }
    def test_simple_notification(self):
        responses.add(
            "POST",
            "https://alert.victorops.com/integrations/generic/20131114/alert/secret-api-key/everyone",
            body=SUCCESS,
        )
        self.plugin.set_option("api_key", "secret-api-key", self.project)
        self.plugin.set_option("routing_key", "everyone", self.project)

        group = self.create_group(message="Hello world", culprit="foo.bar")
        event = self.create_event(group=group, message="Hello world", tags={"level": "warning"})

        rule = Rule.objects.create(project=self.project, label="my rule")

        notification = Notification(event=event, rule=rule)

        with self.options({"system.url-prefix": "http://example.com"}):
            self.plugin.notify(notification)

        request = responses.calls[0].request
        payload = json.loads(request.body)
        assert {
            "message_type": "WARNING",
            "entity_id": group.id,
            "entity_display_name": "Hello world",
            "monitoring_tool": "sentry",
            "state_message": 'Stacktrace\n-----------\n\nStacktrace (most recent call last):\n\n  File "sentry/models/foo.py", line 29, in build_msg\n    string_max_length=self.string_max_length)\n\nMessage\n-----------\n\nHello world',
            "timestamp": int(event.datetime.strftime("%s")),
            "issue_url": "http://example.com/organizations/baz/issues/%s/" % group.id,
        } == payload
Exemple #5
0
    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)
Exemple #6
0
    def test_simple_notification(self):
        responses.add(responses.POST, 'http://example.com')

        group = self.create_group(message='Hello world')
        event = self.create_event(group=group,
                                  message='Hello world',
                                  tags={'level': 'warning'},
                                  id=24)

        rule = Rule.objects.create(project=self.project, label='my rule')

        notification = Notification(event=event, rule=rule)

        self.project.update_option('webhooks:urls', 'http://example.com')

        self.plugin.notify(notification)

        assert len(responses.calls) == 1

        payload = json.loads(responses.calls[0].request.body)

        assert payload['level'] == 'warning'
        assert payload['message'] == 'Hello world'
        assert payload['event']['id'] == 24
        assert payload['event']['event_id'] == event.event_id
Exemple #7
0
    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'
Exemple #8
0
    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"
Exemple #9
0
    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)
Exemple #10
0
    def test_simple_notification(self):
        responses.add('POST',
                      'https://api.pushsafer.net/1/messages.json',
                      body=SUCCESS)
        self.plugin.set_option('privatekey', 'XXXXXXXXXXXXXXXXXXXX',
                               self.project)

        group = self.create_group(message='Hello world', culprit='foo.bar')
        event = self.create_event(
            group=group,
            message='Hello world',
            tags={'level': 'warning'},
        )

        rule = Rule.objects.create(project=self.project, label='my rule')

        notification = Notification(event=event, rule=rule)

        with self.options({'system.url-prefix': 'http://example.com'}):
            self.plugin.notify(notification)

        request = responses.calls[0].request
        payload = parse_qs(request.body)
        assert payload == {
            'm':
            ['{}\n\nTags: level=warning'.format(event.get_legacy_message())],
            't': ['Bar: Hello world'],
            'u': ['http://example.com/baz/bar/issues/{}/'.format(group.id)],
            'ut': ['Issue Details'],
            'd': ['a'],
            'k': ['XXXXXXXXXXXXXXXXXXXX'],
        }
Exemple #11
0
    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)
Exemple #12
0
    def test_emergency_notification(self):
        responses.add('POST', 'https://api.pushover.net/1/messages.json', body=SUCCESS)
        self.plugin.set_option('userkey', 'abcdef', self.project)
        self.plugin.set_option('apikey', 'ghijkl', self.project)
        self.plugin.set_option('priority', '2', self.project)
        self.plugin.set_option('expire', 90, self.project)
        self.plugin.set_option('retry', 30, self.project)

        group = self.create_group(message='Hello world', culprit='foo.bar')
        event = self.create_event(
            group=group,
            message='Hello world',
            tags={'level': 'warning'},
        )

        rule = Rule.objects.create(project=self.project, label='my rule')

        notification = Notification(event=event, rule=rule)

        with self.options({'system.url-prefix': 'http://example.com'}):
            self.plugin.notify(notification)

        request = responses.calls[0].request
        payload = parse_qs(request.body)
        assert payload == {
            'message': ['{}\n\nTags: level=warning'.format(event.get_legacy_message())],
            'title': ['Bar: Hello world'],
            'url': ['http://example.com/baz/bar/issues/{}/'.format(group.id)],
            'url_title': ['Issue Details'],
            'priority': ['2'],
            'user': ['abcdef'],
            'token': ['ghijkl'],
            'expire': ['90'],
            'retry': ['30'],
        }
Exemple #13
0
    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)
Exemple #14
0
    def test_notify_users_renders_interfaces_with_utf8(self, _send_mail,
                                                       _to_email_html,
                                                       _get_title):
        group = self.create_group(first_seen=timezone.now(),
                                  last_seen=timezone.now(),
                                  project=self.project)

        _to_email_html.return_value = u"רונית מגן"
        _get_title.return_value = "Stacktrace"

        event = Event(
            group_id=group.id,
            project_id=self.project.id,
            message="Soubor ji\xc5\xbe existuje",
            # Create interface so get_title will be called on it.
            data={"stacktrace": {
                "frames": [{}]
            }},
        )

        notification = Notification(event=event)

        with self.options({"system.url-prefix": "http://example.com"}):
            self.plugin.notify(notification)

        _get_title.assert_called_once_with()
        _to_email_html.assert_called_once_with(event)
Exemple #15
0
    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)
Exemple #16
0
    def test_simple_notification(self):
        responses.add(
            'GET',
            'https://events.pagerduty.com/generic/2010-04-15/create_event.json',
            body=INVALID_METHOD)
        responses.add(
            'POST',
            'https://events.pagerduty.com/generic/2010-04-15/create_event.json',
            body=SUCCESS)
        self.plugin.set_option('service_key', 'abcdef', self.project)

        group = self.create_group(message='Hello world', culprit='foo.bar')
        event = self.create_event(group=group,
                                  message='Hello world',
                                  tags={'level': 'warning'})

        rule = Rule.objects.create(project=self.project, label='my rule')

        notification = Notification(event=event, rule=rule)

        with self.options({'system.url-prefix': 'http://example.com'}):
            self.plugin.notify(notification)

        request = responses.calls[0].request
        payload = json.loads(request.body)
        assert payload == {
            'client_url':
            'http://example.com',
            'event_type':
            'trigger',
            'contexts': [{
                'text':
                'Issue Details',
                'href':
                'http://example.com/baz/bar/issues/{}/'.format(group.id),
                'type':
                'link',
            }],
            'incident_key':
            group.id,
            'client':
            'sentry',
            'details': {
                'project': self.project.name,
                'release': None,
                'url': 'http://example.com/baz/bar/issues/1/',
                'culprit': group.culprit,
                'platform': None,
                'event_id': event.event_id,
                'tags': {
                    'level': 'warning',
                },
                'datetime': event.datetime.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
            },
            'service_key':
            'abcdef',
            'description':
            event.get_legacy_message(),
        }
Exemple #17
0
 def assert_notify(self, event, emails_sent_to):
     mail.outbox = []
     with self.options({'system.url-prefix':
                        'http://example.com'}), self.tasks():
         self.plugin.notify(Notification(event=event))
     assert len(mail.outbox) == len(emails_sent_to)
     assert sorted(email.to[0]
                   for email in mail.outbox) == sorted(emails_sent_to)
Exemple #18
0
    def rule_notify(self, event, futures):
        rules = []
        for future in futures:
            rules.append(future.rule)
            if not future.kwargs:
                continue
            raise NotImplementedError(
                'The default behavior for notification de-duplication does not support args'
            )

        if hasattr(self, 'notify_digest'):
            project = event.group.project

            # If digest delivery is disabled, we still need to send a
            # notification -- we also need to check rate limits, since
            # ``should_notify`` skips this step if the plugin supports digests.
            if not features.has('projects:digests:deliver', project):
                if self.__is_rate_limited(event.group, event):
                    logger = logging.getLogger('sentry.plugins.{0}'.format(
                        self.get_conf_key()))
                    logger.info(
                        'Notification for project %r dropped due to rate limiting',
                        project)
                    return

                notification = Notification(event=event, rules=rules)
                self.notify(notification)

            if features.has('projects:digests:store', project):
                get_digest_option = lambda key: ProjectOption.objects.get_value(
                    project,
                    '{0}:digests:{1}'.format(self.get_conf_key(), key),
                )
                digest_key = unsplit_key(self, event.group.project)
                immediate_delivery = digests.add(
                    digest_key,
                    event_to_record(event, rules),
                    increment_delay=get_digest_option('increment_delay'),
                    maximum_delay=get_digest_option('maximum_delay'),
                )
                if immediate_delivery:
                    deliver_digest.delay(digest_key)

        else:
            notification = Notification(event=event, rules=rules)
            self.notify(notification)
Exemple #19
0
    def after(self, event, state):
        group = event.group

        notification = Notification(event=event, rule=self.rule)
        for plugin in self.get_plugins():
            if not safe_execute(plugin.should_notify, group=group,
                                event=event):
                continue

            safe_execute(plugin.notify, notification)
Exemple #20
0
    def rule_notify(self, event, futures):
        rules = []
        for future in futures:
            rules.append(future.rule)
            if not future.kwargs:
                continue
            raise NotImplementedError('The default behavior for notification de-duplication does not support args')

        notification = Notification(event=event, rules=rules)
        self.notify(notification)
Exemple #21
0
    def test_notify_users_with_utf8_subject(self):
        group = self.create_group(message=u'רונית מגן')
        event = self.create_event(group=group, message='Hello world')

        notification = Notification(event=event)

        with self.settings(SENTRY_URL_PREFIX='http://example.com'):
            self.plugin.notify(notification)

        msg = mail.outbox[0]
        assert msg.subject == u'[Sentry] [foo Bar] ERROR: רונית מגן'
Exemple #22
0
    def test_notify_users_with_utf8_subject(self):
        group = self.create_group(message=u'רונית מגן')
        event = self.create_event(group=group, message='Hello world')

        notification = Notification(event=event)

        with self.options({'system.url-prefix': 'http://example.com'}):
            self.plugin.notify(notification)

        msg = mail.outbox[0]
        assert msg.subject == u'[Sentry] [foo Bar] ERROR: רונית מגן'
Exemple #23
0
    def test_notify_users_with_utf8_subject(self):
        group = self.create_group(message="Hello world")
        event = self.create_event(group=group, message=u"רונית מגן", tags={"level": "error"})

        notification = Notification(event=event)

        with self.options({"system.url-prefix": "http://example.com"}), self.tasks():
            self.plugin.notify(notification)

        assert len(mail.outbox) == 1
        msg = mail.outbox[0]
        assert msg.subject == u"[Sentry] BAR-1 - רונית מגן"
Exemple #24
0
    def test_notify_users_with_utf8_subject(self):
        group = self.create_group(message='Hello world')
        event = self.create_event(group=group, message=u'רונית מגן', tags={'level': 'error'})

        notification = Notification(event=event)

        with self.options({'system.url-prefix': 'http://example.com'}), self.tasks():
            self.plugin.notify(notification)

        assert len(mail.outbox) == 1
        msg = mail.outbox[0]
        assert msg.subject == u'[Sentry] BAR-1 - רונית מגן'
Exemple #25
0
 def send_notification_helper(self):
     self.initialized_plugin.set_option('receivers', '123', self.project)
     self.initialized_plugin.set_option('api_token', 'api:token', self.project)
     self.initialized_plugin.set_option(
         'message_template',
         '*[Sentry]* {project_name} {tag[level]}: {title}\n{message}\n{url}',
         self.project,
     )
     event = create_sample_event(self.project, platform='python')
     notification = Notification(event=event)
     with patch('requests.sessions.Session.request') as request:
         self.initialized_plugin.notify(notification)
         return request
Exemple #26
0
    def test_simple_notification(self):
        group = self.create_group(message='Hello world')
        event = self.create_event(group=group, message='Hello world', tags={'level': 'error'})

        rule = Rule.objects.create(project=self.project, label='my rule')

        notification = Notification(event=event, rule=rule)

        with self.options({'system.url-prefix': 'http://example.com'}), self.tasks():
            self.plugin.notify(notification)

        msg = mail.outbox[0]
        assert msg.subject == '[Sentry] [foo Bar] ERROR: Hello world'
        assert 'my rule' in msg.alternatives[0][0]
Exemple #27
0
    def test_simple_notification(self):
        group = self.create_group(message="Hello world")
        event = self.create_event(group=group, message="Hello world", tags={"level": "error"})

        rule = Rule.objects.create(project=self.project, label="my rule")

        notification = Notification(event=event, rule=rule)

        with self.options({"system.url-prefix": "http://example.com"}), self.tasks():
            self.plugin.notify(notification)

        msg = mail.outbox[0]
        assert msg.subject == "[Sentry] BAR-1 - Hello world"
        assert "my rule" in msg.alternatives[0][0]
Exemple #28
0
    def rule_notify(self, event, futures):
        from sentry.models import ProjectOption  # Django 1.9 setup issue
        rules = []
        extra = {
            'event_id': event.id,
            'group_id': event.group_id,
            'plugin': self.slug,
        }
        log_event = 'dispatched'
        for future in futures:
            rules.append(future.rule)
            extra['rule_id'] = future.rule.id
            if not future.kwargs:
                continue
            raise NotImplementedError(
                'The default behavior for notification de-duplication does not support args'
            )

        project = event.group.project
        extra['project_id'] = project.id
        if hasattr(self, 'notify_digest') and digests.enabled(project):

            def get_digest_option(key):
                return ProjectOption.objects.get_value(
                    project,
                    get_digest_option_key(self.get_conf_key(), key),
                )

            digest_key = unsplit_key(self, event.group.project)
            extra['digest_key'] = digest_key
            immediate_delivery = digests.add(
                digest_key,
                event_to_record(event, rules),
                increment_delay=get_digest_option('increment_delay'),
                maximum_delay=get_digest_option('maximum_delay'),
            )
            if immediate_delivery:
                deliver_digest.delay(digest_key)
            else:
                log_event = 'digested'

        else:
            notification = Notification(
                event=event,
                rules=rules,
            )
            self.notify(notification)

        self.logger.info('notification.%s' % log_event, extra=extra)
Exemple #29
0
    def test_notify_with_suspect_commits(self):
        release = self.create_release(project=self.project, user=self.user)
        group = self.create_group(project=self.project, first_release=release)
        event = self.create_event(group=group, tags={'sentry:release': release.version})

        notification = Notification(event=event)

        with self.tasks(), self.options({'system.url-prefix': 'http://example.com'}), self.feature('organizations:suggested-commits'):
            self.plugin.notify(notification)

        assert len(mail.outbox) >= 1

        msg = mail.outbox[-1]

        assert 'Suspect Commits' in msg.body
Exemple #30
0
    def test_simple_notification(self):
        group = self.create_group(message='Hello world')
        event = self.create_event(group=group, message='Hello world')

        rule = Rule.objects.create(project=self.project, label='my rule')

        notification = Notification(event=event, rule=rule)

        with self.settings(SENTRY_URL_PREFIX='http://example.com'):
            self.plugin.notify(notification)

        msg = mail.outbox[0]
        assert msg.subject == '[Sentry] [foo Bar] ERROR: Hello world'
        print dir(msg)
        assert 'my rule' in msg.alternatives[0][0]