Beispiel #1
0
 def serialize(self, obj, attrs, user):
     return {
         'id': six.text_type(obj.id),
         'key': TagKey.get_standardized_key(obj.key),
         'name': obj.get_label(),
         'uniqueValues': obj.values_seen,
     }
Beispiel #2
0
    def get(self, request, group):
        tag_keys = TagKey.objects.filter(
            project=group.project,
            status=TagKeyStatus.VISIBLE,
            key__in=GroupTagKey.objects.filter(group=group, ).values('key'),
        )

        # O(N) db access
        data = []
        all_top_values = []
        for tag_key in tag_keys:
            total_values = GroupTagValue.get_value_count(group.id, tag_key.key)
            top_values = GroupTagValue.get_top_values(group.id,
                                                      tag_key.key,
                                                      limit=10)

            all_top_values.extend(top_values)

            data.append({
                'id': six.text_type(tag_key.id),
                'key': TagKey.get_standardized_key(tag_key.key),
                'name': tag_key.get_label(),
                'uniqueValues': tag_key.values_seen,
                'totalValues': total_values,
            })

        # Serialize all of the values at once to avoid O(n) serialize/db queries
        top_values_by_key = defaultdict(list)
        for value in serialize(all_top_values, request.user):
            top_values_by_key[value['key']].append(value)

        for d in data:
            d['topValues'] = top_values_by_key[d['key']]

        return Response(data)
Beispiel #3
0
    def get(self, request, group):
        tag_keys = TagKey.objects.filter(
            project=group.project,
            status=TagKeyStatus.VISIBLE,
            key__in=GroupTagKey.objects.filter(
                group=group,
            ).values('key'),
        )

        # O(N) db access
        data = []
        all_top_values = []
        for tag_key in tag_keys:
            total_values = GroupTagValue.get_value_count(group.id, tag_key.key)
            top_values = GroupTagValue.get_top_values(group.id, tag_key.key, limit=10)

            all_top_values.extend(top_values)

            data.append({
                'id': six.text_type(tag_key.id),
                'key': TagKey.get_standardized_key(tag_key.key),
                'name': tag_key.get_label(),
                'uniqueValues': tag_key.values_seen,
                'totalValues': total_values,
            })

        # Serialize all of the values at once to avoid O(n) serialize/db queries
        top_values_by_key = defaultdict(list)
        for value in serialize(all_top_values, request.user):
            top_values_by_key[value['key']].append(value)

        for d in data:
            d['topValues'] = top_values_by_key[d['key']]

        return Response(data)
Beispiel #4
0
 def serialize(self, obj, attrs, user):
     return {
         'key': TagKey.get_standardized_key(obj.key),
         'name': attrs['name'],
         'value': obj.value,
         'count': obj.times_seen,
         'lastSeen': obj.last_seen,
         'firstSeen': obj.first_seen,
     }
Beispiel #5
0
 def serialize(self, obj, attrs, user):
     return {
         "id": six.text_type(obj.id),
         "key": TagKey.get_standardized_key(obj.key),
         "name": attrs["name"],
         "value": obj.value,
         "count": obj.times_seen,
         "lastSeen": obj.last_seen,
         "firstSeen": obj.first_seen,
     }
Beispiel #6
0
    def passes(self, event, state, **kwargs):
        key = self.get_option('key')
        match = self.get_option('match')
        value = self.get_option('value')

        if not (key and match and value):
            return False

        value = value.lower()
        key = key.lower()

        tags = (
            v.lower()
            for k, v in event.get_tags()
            if k.lower() == key or TagKey.get_standardized_key(k) == key
        )

        if match == MatchType.EQUAL:
            for t_value in tags:
                if t_value == value:
                    return True
            return False

        elif match == MatchType.NOT_EQUAL:
            for t_value in tags:
                if t_value == value:
                    return False
            return True

        elif match == MatchType.STARTS_WITH:
            for t_value in tags:
                if t_value.startswith(value):
                    return True
            return False

        elif match == MatchType.ENDS_WITH:
            for t_value in tags:
                if t_value.endswith(value):
                    return True
            return False

        elif match == MatchType.CONTAINS:
            for t_value in tags:
                if value in t_value:
                    return True
            return False

        elif match == MatchType.NOT_CONTAINS:
            for t_value in tags:
                if value in t_value:
                    return False
            return True
Beispiel #7
0
    def passes(self, event, state, **kwargs):
        key = self.get_option('key')
        match = self.get_option('match')
        value = self.get_option('value')

        if not (key and match and value):
            return False

        value = value.lower()
        key = key.lower()

        tags = (v.lower() for k, v in event.get_tags() if k.lower() == key or TagKey.get_standardized_key(k) == key)

        if match == MatchType.EQUAL:
            for t_value in tags:
                if t_value == value:
                    return True
            return False

        elif match == MatchType.NOT_EQUAL:
            for t_value in tags:
                if t_value == value:
                    return False
            return True

        elif match == MatchType.STARTS_WITH:
            for t_value in tags:
                if t_value.startswith(value):
                    return True
            return False

        elif match == MatchType.ENDS_WITH:
            for t_value in tags:
                if t_value.endswith(value):
                    return True
            return False

        elif match == MatchType.CONTAINS:
            for t_value in tags:
                if value in t_value:
                    return True
            return False

        elif match == MatchType.NOT_CONTAINS:
            for t_value in tags:
                if value in t_value:
                    return False
            return True
Beispiel #8
0
    def get(self, request, project):
        tag_keys = TagKey.objects.filter(
            project=project,
            status=TagKeyStatus.VISIBLE,
        )

        data = []
        for tag_key in tag_keys:
            data.append({
                'id': str(tag_key.id),
                'key': TagKey.get_standardized_key(tag_key.key),
                'name': tag_key.get_label(),
                'uniqueValues': tag_key.values_seen,
            })

        return Response(data)
Beispiel #9
0
    def get_attrs(self, item_list, user):
        tag_labels = {
            t.key: t.get_label()
            for t in TagKey.objects.filter(project=item_list[0].project,
                                           key__in=[i.key for i in item_list])
        }

        result = {}
        for item in item_list:
            key = TagKey.get_standardized_key(item.key)
            try:
                label = tag_labels[item.key]
            except KeyError:
                label = key
            result[item] = {
                'name': label,
                'key': key,
            }
        return result
Beispiel #10
0
    def get_attrs(self, item_list, user):
        tag_labels = {
            t.key: t.get_label()
            for t in TagKey.objects.filter(
                project=item_list[0].project,
                key__in=[i.key for i in item_list]
            )
        }

        result = {}
        for item in item_list:
            key = TagKey.get_standardized_key(item.key)
            try:
                label = tag_labels[item.key]
            except KeyError:
                label = key
            result[item] = {
                'name': label,
                'key': key,
            }
        return result
Beispiel #11
0
    def notify(self, notification):
        event = notification.event
        group = event.group
        project = group.project

        if not self.is_configured(project):
            return

        webhook = self.get_option('webhook', project)
        username = (self.get_option('username', project) or 'Sentry').strip()
        icon_url = self.get_option('icon_url', project)
        channel = (self.get_option('channel', project) or '').strip()

        title = event.message_short.encode('utf-8')
        # TODO(dcramer): we'd like this to be the event culprit, but Sentry
        # does not currently retain it
        if group.culprit:
            culprit = group.culprit.encode('utf-8')
        else:
            culprit = None
        project_name = project.get_full_name().encode('utf-8')

        fields = []

        # They can be the same if there is no culprit
        # So we set culprit to an empty string instead of duplicating the text
        if not self.get_option('exclude_culprit',
                               project) and culprit and title != culprit:
            fields.append({
                'title': 'Culprit',
                'value': culprit,
                'short': False,
            })
        if not self.get_option('exclude_project', project):
            fields.append({
                'title': 'Project',
                'value': project_name,
                'short': True,
            })

        if self.get_option('include_rules', project):
            rules = []
            for rule in notification.rules:
                rule_link = reverse(
                    'sentry-edit-project-rule',
                    args=[group.organization.slug, project.slug, rule.id])
                # Make sure it's an absolute uri since we're sending this
                # outside of Sentry into Slack
                rule_link = absolute_uri(rule_link)
                rules.append((rule_link, rule.label.encode('utf-8')))

            if rules:
                fields.append({
                    'title':
                    'Triggered By',
                    'value':
                    ', '.join('<%s | %s>' % r for r in rules),
                    'short':
                    False,
                })

        if self.get_option('include_tags', project):
            included_tags = set(
                self.get_tag_list('included_tag_keys', project) or [])
            excluded_tags = set(
                self.get_tag_list('excluded_tag_keys', project) or [])
            for tag_key, tag_value in self._get_tags(event):
                key = tag_key.lower()
                std_key = TagKey.get_standardized_key(key)
                if included_tags and key not in included_tags and std_key not in included_tags:
                    continue
                if excluded_tags and (key in excluded_tags
                                      or std_key in excluded_tags):
                    continue
                fields.append({
                    'title': tag_key.encode('utf-8'),
                    'value': tag_value.encode('utf-8'),
                    'short': True,
                })

        payload = {
            'attachments': [{
                'fallback':
                '[%s] %s' % (project_name, title),
                'title':
                title,
                'title_link':
                self.add_notification_referrer_param(group.get_absolute_url()),
                'color':
                self.color_for_event(event),
                'fields':
                fields,
            }]
        }

        if username:
            payload['username'] = username.encode('utf-8')

        if channel:
            payload['channel'] = channel

        if icon_url:
            payload['icon_url'] = icon_url

        values = {'payload': json.dumps(payload)}

        # Apparently we've stored some bad data from before we used `URLField`.
        webhook = webhook.strip(' ')
        return http.safe_urlopen(webhook, method='POST', data=values)
Beispiel #12
0
    def notify(self, notification):
        event = notification.event
        group = event.group
        project = group.project

        if not self.is_configured(project):
            return

        webhook = self.get_option('webhook', project)
        username = (self.get_option('username', project) or 'Sentry').strip()
        icon_url = self.get_option('icon_url', project)
        channel = (self.get_option('channel', project) or '').strip()
        sort_on_tag = self.get_option('sort_on_tag', project)
        send_to_root_too = self.get_option('send_to_root_too', project)

        title = event.message_short.encode('utf-8')
        # TODO(dcramer): we'd like this to be the event culprit, but Sentry
        # does not currently retain it
        if group.culprit:
            culprit = group.culprit.encode('utf-8')
        else:
            culprit = None
        project_name = get_project_full_name(project).encode('utf-8')

        fields = []

        # They can be the same if there is no culprit
        # So we set culprit to an empty string instead of duplicating the text
        if culprit and title != culprit:
            fields.append({
                'title': 'Culprit',
                'value': culprit,
                'short': False,
            })

        fields.append({
            'title': 'Project',
            'value': project_name,
            'short': True,
        })

        if self.get_option('include_rules', project):
            rules = []
            for rule in notification.rules:
                rule_link = reverse('sentry-edit-project-rule', args=[
                    group.organization.slug, project.slug, rule.id
                ])
                # Make sure it's an absolute uri since we're sending this
                # outside of Sentry into Slack
                rule_link = absolute_uri(rule_link)
                rules.append((rule_link, rule.label.encode('utf-8')))

            if rules:
                fields.append({
                    'title': 'Triggered By',
                    'value': ', '.join('<%s | %s>' % r for r in rules),
                    'short': False,
                })

        if self.get_option('include_tags', project):
            included_tags = set(self.get_tag_list('included_tag_keys', project) or [])
            excluded_tags = set(self.get_tag_list('excluded_tag_keys', project) or [])
            for tag_key, tag_value in self._get_tags(event):
                key = tag_key.lower()
                std_key = TagKey.get_standardized_key(key)
                if included_tags and key not in included_tags and std_key not in included_tags:
                    continue
                if excluded_tags and (key in excluded_tags or std_key in excluded_tags):
                    continue
                fields.append({
                    'title': tag_key.encode('utf-8'),
                    'value': tag_value.encode('utf-8'),
                    'short': True,
                })

        payload = {
            'parse': 'none',
            'attachments': [{
                'fallback': '[%s] %s' % (project_name, title),
                'title': title,
                'title_link': group.get_absolute_url(),
                'color': self.color_for_group(group),
                'fields': fields,
            }]
        }

        # Apparently we've stored some bad data from before we used `URLField`.
        webhook = webhook.strip(' ')

        if username:
            payload['username'] = username.encode('utf-8')

        if channel:
            payload['channel'] = channel

        if icon_url:
            payload['icon_url'] = icon_url

        if sort_on_tag:
            if send_to_root_too:
                http.safe_urlopen(webhook, method='POST', data={'payload': json.dumps(payload)})

            sort_on_tag_key = (self.get_option('sort_on_tag_key', project) or 'application_name').strip()
            groups = [
                {"tag_values": (self.get_option('group_1_tag_values', project).split(',') or []),
                 "channel": (self.get_option('group_1_channel', project) or '').strip()},
                {"tag_values": (self.get_option('group_2_tag_values', project).split(',') or []),
                 "channel": (self.get_option('group_2_channel', project) or '').strip()},
                {"tag_values": (self.get_option('group_3_tag_values', project).split(',') or []),
                 "channel": (self.get_option('group_3_channel', project) or '').strip()}]

            for key, value in self._get_tags(event):
                if sort_on_tag_key == key:
                    tag_value = value
                    break
            else:
                # Tag does not exist, no need to check the groups.
                return

            for group in groups:
                if tag_value in group["tag_values"]:
                    payload['channel'] = group["channel"]

                    http.safe_urlopen(webhook, method='POST', data={'payload': json.dumps(payload)})
            return
        else:
            return http.safe_urlopen(webhook, method='POST', data={'payload': json.dumps(payload)})