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, }
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)
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)
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, }
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, }
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
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
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)
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
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
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)
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)})