Exemplo n.º 1
0
    def get_group_tag_keys_and_top_values(self, project_id, group_id, environment_id, user=None):
        from sentry import tagstore
        start, end = self.get_time_range()
        filters = {
            'project_id': [project_id],
            'environment': [environment_id],
            'issue': [group_id],
        }
        aggregations = [
            ['topK(10)', 'tags.value', 'top'],
            ['count', '', 'count'],
            ['uniq', 'tags.key', 'uniq'],
        ]
        results = snuba.query(start, end, ['tags.key'], None, filters,
                              aggregations, arrayjoin='tags')

        return [{
            'id': key,
            'name': tagstore.get_tag_key_label(key),
            'key': tagstore.get_standardized_key(key),
            'uniqueValues': res['uniq'],
            'totalValues': res['count'],
            'topValues': [{
                'id': val,
                'name': tagstore.get_tag_value_label(key, val),
                'key': tagstore.get_standardized_key(key),
                'value': val,
            } for val in res['top']],
        } for key, res in six.iteritems(results)]
Exemplo n.º 2
0
    def get_group_tag_keys_and_top_values(self, project_id, group_id, environment_id, user=None):
        from sentry import tagstore
        start, end = self.get_time_range()
        filters = {
            'project_id': [project_id],
            'environment': [environment_id],
            'issue': [group_id],
        }
        aggregations = [
            ['count()', '', 'count'],
            ['topK(10)', 'tags_value', 'top'],
            ['uniq', 'tags_value', 'uniq'],
        ]
        conditions = [
            ['tags_value', 'IS NOT NULL', None],
        ]
        results = snuba.query(start, end, ['tags_key'], conditions, filters, aggregations)

        return [{
            'id': key,
            'name': tagstore.get_tag_key_label(key),
            'key': tagstore.get_standardized_key(key),
            'uniqueValues': res['uniq'],
            'totalValues': res['count'],
            'topValues': [{
                'id': val,
                'name': tagstore.get_tag_value_label(key, val),
                'key': tagstore.get_standardized_key(key),
                'value': val,
            } for val in res['top']],
        } for key, res in six.iteritems(results)]
    def get(self, request, project):
        try:
            environment_id = self._get_environment_id_from_request(request, project.organization_id)
        except Environment.DoesNotExist:
            tag_keys = []
        else:
            tag_keys = sorted(
                tagstore.get_tag_keys(
                    project.id,
                    environment_id,
                ),
                key=lambda x: x.key)

        data = []
        for tag_key in tag_keys:
            data.append(
                {
                    'key': tagstore.get_standardized_key(tag_key.key),
                    'name': tagstore.get_tag_key_label(tag_key.key),
                    'uniqueValues': tag_key.values_seen,
                    'canDelete': tag_key.key not in PROTECTED_TAG_KEYS,
                }
            )

        return Response(data)
Exemplo n.º 4
0
 def serialize(self, obj, attrs, user):
     return {
         'id': six.text_type(obj.id),
         'key': tagstore.get_standardized_key(obj.key),
         'name': obj.get_label(),
         'uniqueValues': obj.values_seen,
     }
Exemplo n.º 5
0
    def get(self, request, group):
        group_tag_keys = tagstore.get_group_tag_keys(group.id)

        # O(N) db access
        data = []
        all_top_values = []
        for group_tag_key in group_tag_keys:
            total_values = tagstore.get_group_tag_value_count(group.id, group_tag_key.key)
            top_values = tagstore.get_top_group_tag_values(group.id, group_tag_key.key, limit=10)

            all_top_values.extend(top_values)

            data.append(
                {
                    'id': six.text_type(group_tag_key.id),
                    'key': tagstore.get_standardized_key(group_tag_key.key),
                    'name': tagstore.get_tag_key_label(group_tag_key.key),
                    'uniqueValues': group_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)
Exemplo n.º 6
0
 def data_fn(offset, limit):
     with sentry_sdk.start_span(op="discover.endpoint", description="discover_query"):
         with self.handle_query_errors():
             facets = discover.get_performance_facets(
                 query=request.GET.get("query"),
                 params=params,
                 referrer="api.organization-events-facets-performance.top-tags",
                 aggregate_column=aggregate_column,
                 orderby=orderby,
                 offset=offset,
                 limit=limit,
             )
         with sentry_sdk.start_span(
             op="discover.endpoint", description="populate_results"
         ) as span:
             span.set_data("facet_count", len(facets or []))
             resp = defaultdict(lambda: {"key": "", "value": {}})
             for row in facets:
                 values = resp[row.key]
                 values["key"] = tagstore.get_standardized_key(row.key)
                 values["value"] = {
                     "name": tagstore.get_tag_value_label(row.key, row.value),
                     "value": row.value,
                     "count": row.count,
                     "frequency": row.frequency,
                     "aggregate": row.performance,
                     "comparison": row.comparison,
                     "sumdelta": row.sumdelta,
                 }
         return {"data": list(resp.values())}
Exemplo n.º 7
0
    def build_tags_widget(self, project, event):
        if not self.get_option("include_tags", project):
            return None

        tags = []
        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 = tagstore.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

            tags.append({
                "keyValue": {
                    "topLabel": tag_key.encode("utf-8"),
                    "content": tag_value.encode("utf-8")
                }
            })
        return tags
Exemplo n.º 8
0
    def get(self, request, project):
        try:
            environment_id = self._get_environment_id_from_request(request, project.organization_id)
        except Environment.DoesNotExist:
            tag_keys = []
        else:
            tag_keys = sorted(
                tagstore.get_tag_keys(
                    project.id,
                    environment_id,
                    # We might be able to stop including these values, but this
                    # is a pretty old endpoint, so concerned about breaking
                    # existing api consumers.
                    include_values_seen=True,
                ),
                key=lambda x: x.key)

        data = []
        for tag_key in tag_keys:
            data.append(
                {
                    'key': tagstore.get_standardized_key(tag_key.key),
                    'name': tagstore.get_tag_key_label(tag_key.key),
                    'uniqueValues': tag_key.values_seen,
                    'canDelete': tag_key.key not in PROTECTED_TAG_KEYS,
                }
            )

        return Response(data)
Exemplo n.º 9
0
    def get(self, request, group):
        grouptagkeys = list(
            GroupTagKey.objects.filter(group_id=group.id).values_list(
                'key', flat=True))

        tag_keys = tagstore.get_tag_keys(group.project_id, grouptagkeys)

        # 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': tagstore.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)
Exemplo n.º 10
0
    def get(self, request, project):
        try:
            environment_id = self._get_environment_id_from_request(
                request, project.organization_id)
        except Environment.DoesNotExist:
            tag_keys = []
        else:
            tag_keys = sorted(
                tagstore.get_tag_keys(
                    project.id,
                    environment_id,
                    # We might be able to stop including these values, but this
                    # is a pretty old endpoint, so concerned about breaking
                    # existing api consumers.
                    include_values_seen=True,
                ),
                key=lambda x: x.key)

        data = []
        for tag_key in tag_keys:
            data.append({
                'key': tagstore.get_standardized_key(tag_key.key),
                'name': tagstore.get_tag_key_label(tag_key.key),
                'uniqueValues': tag_key.values_seen,
                'canDelete': tag_key.key not in PROTECTED_TAG_KEYS,
            })

        return Response(data)
Exemplo n.º 11
0
    def get(self, request, project):
        try:
            environment_id = self._get_environment_id_from_request(request, project.organization_id)
        except Environment.DoesNotExist:
            tag_keys = []
        else:
            tag_keys = sorted(
                tagstore.get_tag_keys(
                    project.id,
                    environment_id,
                ),
                key=lambda x: x.key)

        data = []
        for tag_key in tag_keys:
            data.append(
                {
                    'id': six.text_type(tag_key.id),
                    'key': tagstore.get_standardized_key(tag_key.key),
                    'name': tagstore.get_tag_key_label(tag_key.key),
                    'uniqueValues': tag_key.values_seen,
                    'canDelete': tag_key.key not in PROTECTED_TAG_KEYS,
                }
            )

        return Response(data)
        def data_fn(offset, limit):
            with sentry_sdk.start_span(op="discover.endpoint",
                                       description="discover_query"):
                referrer = "api.organization-events-facets-performance-histogram.top-tags"
                tag_data = query_tag_data(
                    filter_query=filter_query,
                    aggregate_column=aggregate_column,
                    referrer=referrer,
                    params=params,
                )

                if not tag_data:
                    return {"data": []}

                results = query_facet_performance_key_histogram(
                    tag_data=tag_data,
                    tag_key=tag_key,
                    filter_query=filter_query,
                    aggregate_column=aggregate_column,
                    referrer=referrer,
                    orderby=self.get_orderby(request),
                    params=params,
                    limit=limit,
                )

                if not results:
                    return {"data": []}

                for row in results["data"]:
                    row["tags_value"] = tagstore.get_tag_value_label(
                        row["tags_key"], row["tags_value"])
                    row["tags_key"] = tagstore.get_standardized_key(
                        row["tags_key"])

                return results
Exemplo n.º 13
0
    def get(self, request, organization):
        with sentry_sdk.start_span(op="discover.endpoint",
                                   description="filter_params") as span:
            span.set_data("organization", organization)
            if not features.has("organizations:discover-basic",
                                organization,
                                actor=request.user):
                return Response(status=404)
            try:
                params = self.get_filter_params(request, organization)
            except NoProjects:
                return Response([])
            params = self.quantize_date_params(request, params)
            self._validate_project_ids(request, organization, params)

        with sentry_sdk.start_span(op="discover.endpoint",
                                   description="discover_query"):
            try:
                facets = discover.get_facets(
                    query=request.GET.get("query"),
                    params=params,
                    referrer="api.organization-events-facets.top-tags",
                )
            except (discover.InvalidSearchQuery,
                    snuba.QueryOutsideRetentionError) as error:
                raise ParseError(detail=six.text_type(error))

        with sentry_sdk.start_span(op="discover.endpoint",
                                   description="populate_results") as span:
            span.set_data("facet_count", len(facets or []))
            resp = defaultdict(lambda: {"key": "", "topValues": []})
            for row in facets:
                values = resp[row.key]
                values["key"] = tagstore.get_standardized_key(row.key)
                values["topValues"].append({
                    "name":
                    tagstore.get_tag_value_label(row.key, row.value),
                    "value":
                    row.value,
                    "count":
                    row.count,
                })
            if "project" in resp:
                # Replace project ids with slugs as that is what we generally expose to users
                # and filter out projects that the user doesn't have access too.
                projects = {
                    p.id: p.slug
                    for p in self.get_projects(request, organization)
                }
                filtered_values = []
                for v in resp["project"]["topValues"]:
                    if v["value"] in projects:
                        name = projects[v["value"]]
                        v.update({"name": name})
                        filtered_values.append(v)

                resp["project"]["topValues"] = filtered_values

        return Response(resp.values())
Exemplo n.º 14
0
    def serialize(self, obj, attrs, user):
        from sentry import tagstore

        return {
            'key': tagstore.get_standardized_key(obj.key),
            'name': tagstore.get_tag_key_label(obj.key),
            'uniqueValues': obj.values_seen,
        }
Exemplo n.º 15
0
    def serialize(self, obj, attrs, user):
        from sentry import tagstore

        return {
            'key': tagstore.get_standardized_key(obj.key),
            'name': tagstore.get_tag_key_label(obj.key),
            'uniqueValues': obj.values_seen,
        }
Exemplo n.º 16
0
    def get_attrs(self, item_list, user):
        result = {}
        for item in item_list:
            key = tagstore.get_standardized_key(item.key)
            result[item] = {
                'name': tagstore.get_tag_key_label(item.key),
                'key': key,
            }

        return result
Exemplo n.º 17
0
 def serialize(self, obj, attrs, user):
     return {
         'id': six.text_type(obj.id),
         'name': attrs['name'],
         'key': tagstore.get_standardized_key(obj.key),
         'value': obj.value,
         'count': obj.times_seen,
         'lastSeen': obj.last_seen,
         'firstSeen': obj.first_seen,
     }
Exemplo n.º 18
0
    def get(self, request, organization):
        if not features.has("organizations:discover-basic",
                            organization,
                            actor=request.user):
            return Response(status=404)
        try:
            params = self.get_filter_params(request, organization)
        except OrganizationEventsError as error:
            raise ParseError(detail=six.text_type(error))
        except NoProjects:
            return Response({"detail": "A valid project must be included."},
                            status=400)
        try:
            self._validate_project_ids(request, organization, params)
        except OrganizationEventsError as error:
            return Response({"detail": six.text_type(error)}, status=400)

        try:
            facets = discover.get_facets(
                query=request.GET.get("query"),
                params=params,
                referrer="api.organization-events-facets.top-tags",
            )
        except discover.InvalidSearchQuery as error:
            raise ParseError(detail=six.text_type(error))

        resp = defaultdict(lambda: {"key": "", "topValues": []})
        for row in facets:
            values = resp[row.key]
            values["key"] = tagstore.get_standardized_key(row.key)
            values["topValues"].append({
                "name":
                tagstore.get_tag_value_label(row.key, row.value),
                "value":
                row.value,
                "count":
                row.count,
            })
        if "project" in resp:
            # Replace project ids with slugs as that is what we generally expose to users
            # and filter out projects that the user doesn't have access too.
            projects = {
                p.id: p.slug
                for p in self.get_projects(request, organization)
            }
            filtered_values = []
            for v in resp["project"]["topValues"]:
                if v["value"] in projects:
                    name = projects[v["value"]]
                    v.update({"name": name})
                    filtered_values.append(v)

            resp["project"]["topValues"] = filtered_values

        return Response(resp.values())
Exemplo n.º 19
0
    def serialize(self, obj, attrs, user):
        from sentry import tagstore

        return {
            'key': tagstore.get_standardized_key(obj.key),
            'name': tagstore.get_tag_value_label(obj.key, obj.value),
            'value': obj.value,
            'count': obj.times_seen,
            'lastSeen': obj.last_seen,
            'firstSeen': obj.first_seen,
        }
Exemplo n.º 20
0
    def serialize(self, obj, attrs, user):
        from sentry import tagstore

        return {
            'key': tagstore.get_standardized_key(obj.key),
            'name': tagstore.get_tag_value_label(obj.key, obj.value),
            'value': obj.value,
            'count': obj.times_seen,
            'lastSeen': obj.last_seen,
            'firstSeen': obj.first_seen,
        }
Exemplo n.º 21
0
    def serialize(self, obj, attrs, user):
        from sentry import tagstore

        return {
            'id': six.text_type(obj.id),
            'name': attrs['name'],
            'key': tagstore.get_standardized_key(obj.key),
            'value': obj.value,
            'count': obj.times_seen,
            'lastSeen': obj.last_seen,
            'firstSeen': obj.first_seen,
        }
Exemplo n.º 22
0
    def serialize(self, obj, attrs, user):
        from sentry import tagstore

        return {
            "id": six.text_type(obj.id),
            "name": attrs["name"],
            "key": tagstore.get_standardized_key(obj.key),
            "value": obj.value,
            "count": obj.times_seen,
            "lastSeen": obj.last_seen,
            "firstSeen": obj.first_seen,
        }
Exemplo n.º 23
0
    def get_attrs(self, item_list, user):
        from sentry import tagstore

        result = {}
        for item in item_list:
            key = tagstore.get_standardized_key(item.key)
            result[item] = {
                'name': tagstore.get_tag_key_label(item.key),
                'key': key,
            }

        return result
Exemplo n.º 24
0
    def serialize(self, obj, attrs, user):
        from sentry import tagstore

        output = {
            'key': tagstore.get_standardized_key(obj.key),
            'name': tagstore.get_tag_key_label(obj.key),
            'uniqueValues': obj.values_seen,
        }
        if obj.count is not None:
            output['totalValues'] = obj.count
        if obj.top_values is not None:
            output['topValues'] = serialize(obj.top_values, user)
        return output
Exemplo n.º 25
0
    def serialize(self, obj, attrs, user):
        from sentry import tagstore

        output = {
            'key': tagstore.get_standardized_key(obj.key),
            'name': tagstore.get_tag_key_label(obj.key),
            'uniqueValues': obj.values_seen,
        }
        if obj.count is not None:
            output['totalValues'] = obj.count
        if obj.top_values is not None:
            output['topValues'] = serialize(obj.top_values, user)
        return output
Exemplo n.º 26
0
    def get(self, request, project):
        tag_keys = tagstore.get_tag_keys(project.id)

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

        return Response(data)
Exemplo n.º 27
0
    def passes(self, event, state):
        latest_release = self.get_latest_release(event)
        if not latest_release:
            return False

        releases = (v.lower() for k, v in event.tags if k.lower() == "release"
                    or tagstore.get_standardized_key(k) == "release")

        for release in releases:
            if release == latest_release.version:
                return True

        return False
Exemplo n.º 28
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 tagstore.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
Exemplo n.º 29
0
    def get(self, request, organization):
        if not self.has_feature(organization, request):
            return Response(status=404)

        try:
            params = self.get_snuba_params(request, organization)
        except NoProjects:
            return Response([])

        with sentry_sdk.start_span(op="discover.endpoint",
                                   description="discover_query"):
            with self.handle_query_errors():
                facets = discover.get_facets(
                    query=request.GET.get("query"),
                    params=params,
                    referrer="api.organization-events-facets.top-tags",
                )

        with sentry_sdk.start_span(op="discover.endpoint",
                                   description="populate_results") as span:
            span.set_data("facet_count", len(facets or []))
            resp = defaultdict(lambda: {"key": "", "topValues": []})
            for row in facets:
                values = resp[row.key]
                values["key"] = tagstore.get_standardized_key(row.key)
                values["topValues"].append({
                    "name":
                    tagstore.get_tag_value_label(row.key, row.value),
                    "value":
                    row.value,
                    "count":
                    row.count,
                })
            if "project" in resp:
                # Replace project ids with slugs as that is what we generally expose to users
                # and filter out projects that the user doesn't have access too.
                projects = {
                    p.id: p.slug
                    for p in self.get_projects(request, organization)
                }
                filtered_values = []
                for v in resp["project"]["topValues"]:
                    if v["value"] in projects:
                        name = projects[v["value"]]
                        v.update({"name": name})
                        filtered_values.append(v)

                resp["project"]["topValues"] = filtered_values

        return Response(list(resp.values()))
Exemplo n.º 30
0
    def get_event_payload(self, event):
        props = {
            'event_id': event.event_id,
            'project_id': event.project.slug,
            'transaction': event.get_tag('transaction') or '',
            'release': event.get_tag('sentry:release') or '',
            'environment': event.get_tag('environment') or '',
            'type': event.get_event_type(),
        }
        props['tags'] = [[k.format(tagstore.get_standardized_key(k)), v]
                         for k, v in event.get_tags()]
        for key, value in six.iteritems(event.interfaces):
            if key == 'request':
                headers = value.headers
                if not isinstance(headers, dict):
                    headers = dict(headers or ())

                props.update({
                    'request_url': value.url,
                    'request_method': value.method,
                    'request_referer': headers.get('Referer', ''),
                })
            elif key == 'exception':
                exc = value.values[0]
                props.update({
                    'exception_type': exc.type,
                    'exception_value': exc.value,
                })
            elif key == 'logentry':
                props.update({
                    'message': value.formatted or value.message,
                })
            elif key in ('csp', 'expectct', 'expectstable', 'hpkp'):
                props.update({
                    '{}_{}'.format(key.rsplit('.', 1)[-1].lower(), k): v
                    for k, v in six.iteritems(value.to_json())
                })
            elif key == 'user':
                user_payload = {}
                if value.id:
                    user_payload['user_id'] = value.id
                if value.email:
                    user_payload['user_email_hash'] = md5_text(
                        value.email).hexdigest()
                if value.ip_address:
                    user_payload['user_ip_trunc'] = anonymize_ip(
                        value.ip_address)
                if user_payload:
                    props.update(user_payload)
        return props
Exemplo n.º 31
0
    def serialize(self, obj, attrs, user):
        from sentry import tagstore

        output = {
            "key": tagstore.get_standardized_key(obj.key),
            "name": tagstore.get_tag_key_label(obj.key),
        }
        if obj.values_seen is not None:
            output["uniqueValues"] = obj.values_seen
        if obj.count is not None:
            output["totalValues"] = obj.count
        if obj.top_values is not None:
            output["topValues"] = serialize(obj.top_values, user)
        return output
Exemplo n.º 32
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 tagstore.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
Exemplo n.º 33
0
    def get_event_payload_properties(self, event):
        props = {
            "event_id": event.event_id,
            "issue_id": event.group_id,
            "project_id": event.project.slug,
            "transaction": event.get_tag("transaction") or "",
            "release": event.get_tag("sentry:release") or "",
            "environment": event.get_tag("environment") or "",
            "type": event.get_event_type(),
        }
        props["tags"] = [[k.format(tagstore.get_standardized_key(k)), v]
                         for k, v in event.tags]
        for key, value in six.iteritems(event.interfaces):
            if key == "request":
                headers = value.headers
                if not isinstance(headers, dict):
                    headers = dict(headers or ())

                props.update({
                    "request_url": value.url,
                    "request_method": value.method,
                    "request_referer": headers.get("Referer", ""),
                })
            elif key == "exception":
                exc = value.values[0]
                props.update({
                    "exception_type": exc.type,
                    "exception_value": exc.value
                })
            elif key == "logentry":
                props.update({"message": value.formatted or value.message})
            elif key in ("csp", "expectct", "expectstable", "hpkp"):
                props.update({
                    u"{}_{}".format(key.rsplit(".", 1)[-1].lower(), k): v
                    for k, v in six.iteritems(value.to_json())
                })
            elif key == "user":
                user_payload = {}
                if value.id:
                    user_payload["user_id"] = value.id
                if value.email:
                    user_payload["user_email_hash"] = md5_text(
                        value.email).hexdigest()
                if value.ip_address:
                    user_payload["user_ip_trunc"] = anonymize_ip(
                        value.ip_address)
                if user_payload:
                    props.update(user_payload)
        return props
Exemplo n.º 34
0
    def get(self, request, project):
        tag_keys = sorted(tagstore.get_tag_keys(project.id), key=lambda x: x.key)

        data = []
        for tag_key in tag_keys:
            data.append(
                {
                    'id': six.text_type(tag_key.id),
                    'key': tagstore.get_standardized_key(tag_key.key),
                    'name': tagstore.get_tag_key_label(tag_key.key),
                    'uniqueValues': tag_key.values_seen,
                }
            )

        return Response(data)
Exemplo n.º 35
0
    def get_event_payload(self, event):
        props = {
            'event_id': event.event_id,
            'project_id': event.project.slug,
            'transaction': event.get_tag('transaction') or '',
            'release': event.get_tag('sentry:release') or '',
            'environment': event.get_tag('environment') or '',
            'type': event.get_event_type(),
        }
        props['tags'] = [[k.format(tagstore.get_standardized_key(k)), v]
                         for k, v in event.get_tags()]
        for key, value in six.iteritems(event.interfaces):
            if key == 'request':
                headers = value.headers
                if not isinstance(headers, dict):
                    headers = dict(headers or ())

                props.update({
                    'request_url': value.url,
                    'request_method': value.method,
                    'request_referer': headers.get('Referer', ''),
                })
            elif key == 'exception':
                exc = value.values[0]
                props.update({
                    'exception_type': exc.type,
                    'exception_value': exc.value,
                })
            elif key == 'logentry':
                props.update({
                    'message': value.formatted or value.message,
                })
            elif key in ('csp', 'expectct', 'expectstable', 'hpkp'):
                props.update({
                    '{}_{}'.format(key.rsplit('.', 1)[-1].lower(), k): v
                    for k, v in six.iteritems(value.to_json())
                })
            elif key == 'user':
                user_payload = {}
                if value.id:
                    user_payload['user_id'] = value.id
                if value.email:
                    user_payload['user_email_hash'] = md5_text(value.email).hexdigest()
                if value.ip_address:
                    user_payload['user_ip_trunc'] = anonymize_ip(value.ip_address)
                if user_payload:
                    props.update(user_payload)
        return props
Exemplo n.º 36
0
def build_tag_fields(event_for_tags, tags: Mapping[str, str] = None):
    fields = []
    if tags:
        event_tags = event_for_tags.tags if event_for_tags else []
        for key, value in event_tags:
            std_key = tagstore.get_standardized_key(key)
            if std_key not in tags:
                continue

            labeled_value = tagstore.get_tag_value_label(key, value)
            fields.append({
                "title": std_key.encode("utf-8"),
                "value": labeled_value.encode("utf-8"),
                "short": True,
            })
    return fields
Exemplo n.º 37
0
    def serialize(self, obj, attrs, user):
        from sentry import tagstore
        key = tagstore.get_standardized_key(obj.key)
        serialized = {
            'key': key,
            'name': tagstore.get_tag_value_label(obj.key, obj.value),
            'value': obj.value,
            'count': obj.times_seen,
            'lastSeen': obj.last_seen,
            'firstSeen': obj.first_seen,
        }

        query = convert_user_tag_to_query(key, obj.value)
        if query:
            serialized['query'] = query

        return serialized
Exemplo n.º 38
0
    def serialize(self, obj, attrs, user):
        from sentry import tagstore
        key = tagstore.get_standardized_key(obj.key)
        serialized = {
            'key': key,
            'name': tagstore.get_tag_value_label(obj.key, obj.value),
            'value': obj.value,
            'count': obj.times_seen,
            'lastSeen': obj.last_seen,
            'firstSeen': obj.first_seen,
        }

        query = convert_user_tag_to_query(key, obj.value)
        if query:
            serialized['query'] = query

        return serialized
Exemplo n.º 39
0
    def serialize(self, obj, attrs, user):
        from sentry import tagstore

        key = tagstore.get_standardized_key(obj.key)
        serialized = {
            "key": key,
            "name": tagstore.get_tag_value_label(obj.key, obj.value),
            "value": obj.value,
            "count": obj.times_seen,
            "lastSeen": obj.last_seen,
            "firstSeen": obj.first_seen,
        }

        query = convert_user_tag_to_query(key, obj.value)
        if query:
            serialized["query"] = query

        return serialized
Exemplo n.º 40
0
def build_tag_fields(
    event_for_tags: Any,
    tags: Optional[Set[str]] = None
) -> Sequence[Mapping[str, Union[str, bool]]]:
    fields = []
    if tags:
        event_tags = event_for_tags.tags if event_for_tags else []
        for key, value in event_tags:
            std_key = tagstore.get_standardized_key(key)
            if std_key not in tags:
                continue

            labeled_value = tagstore.get_tag_value_label(key, value)
            fields.append({
                "title": std_key.encode("utf-8"),
                "value": labeled_value.encode("utf-8"),
                "short": True,
            })
    return fields
Exemplo n.º 41
0
    def get(self, request, organization):
        if not self.has_feature(organization, request):
            return Response(status=404)

        try:
            params = self.get_snuba_params(request, organization)
        except NoProjects:
            return Response([])

        aggregate_column = request.GET.get("aggregateColumn", "duration")
        orderby = request.GET.getlist("order", None)

        with sentry_sdk.start_span(op="discover.endpoint",
                                   description="discover_query"):
            with self.handle_query_errors():
                facets = discover.get_performance_facets(
                    query=request.GET.get("query"),
                    params=params,
                    referrer=
                    "api.organization-events-facets-performance.top-tags",
                    aggregate_column=aggregate_column,
                    orderby=orderby,
                )

        with sentry_sdk.start_span(op="discover.endpoint",
                                   description="populate_results") as span:
            span.set_data("facet_count", len(facets or []))
            resp = defaultdict(lambda: {"key": "", "topValues": []})
            for row in facets:
                values = resp[row.key]
                values["key"] = tagstore.get_standardized_key(row.key)
                values["topValues"].append({
                    "name":
                    tagstore.get_tag_value_label(row.key, row.value),
                    "value":
                    row.value,
                    "count":
                    row.count,
                    "aggregate":
                    row.performance,
                })
        return Response(list(resp.values()))
Exemplo n.º 42
0
    def get_attrs(self, item_list, user):
        tag_labels = {
            t.key: t.get_label()
            for t in tagstore.get_tag_keys(item_list[0].project_id,
                                           [i.key for i in item_list])
        }

        result = {}
        for item in item_list:
            key = tagstore.get_standardized_key(item.key)
            try:
                label = tag_labels[item.key]
            except KeyError:
                label = key
            result[item] = {
                'name': label,
                'key': key,
            }

        return result
Exemplo n.º 43
0
def build_attachment(group, event=None, tags=None, identity=None, actions=None, rules=None):
    # XXX(dcramer): options are limited to 100 choices, even when nested
    status = group.get_status()

    members = get_member_assignees(group)
    teams = get_team_assignees(group)

    logo_url = absolute_uri(get_asset_url('sentry', 'images/sentry-email-avatar.png'))
    color = LEVEL_TO_COLOR.get(
        event.get_tag('level'),
        'error') if event else LEVEL_TO_COLOR['error']

    text = build_attachment_text(group, event) or ''

    if actions is None:
        actions = []

    assignee = get_assignee(group)

    resolve_button = {
        'name': 'resolve_dialog',
        'value': 'resolve_dialog',
        'type': 'button',
        'text': 'Resolve...',
    }

    ignore_button = {
        'name': 'status',
        'value': 'ignored',
        'type': 'button',
        'text': 'Ignore',
    }

    has_releases = Release.objects.filter(
        projects=group.project,
        organization_id=group.project.organization_id
    ).exists()

    if not has_releases:
        resolve_button.update({
            'name': 'status',
            'text': 'Resolve',
            'value': 'resolved',
        })

    if status == GroupStatus.RESOLVED:
        resolve_button.update({
            'name': 'status',
            'text': 'Unresolve',
            'value': 'unresolved',
        })

    if status == GroupStatus.IGNORED:
        ignore_button.update({
            'text': 'Stop Ignoring',
            'value': 'unresolved',
        })

    option_groups = []

    if teams:
        option_groups.append({
            'text': 'Teams',
            'options': teams,
        })

    if members:
        option_groups.append({
            'text': 'People',
            'options': members,
        })

    payload_actions = [
        resolve_button,
        ignore_button,
        {
            'name': 'assign',
            'text': 'Select Assignee...',
            'type': 'select',
            'selected_options': [assignee],
            'option_groups': option_groups,
        },
    ]

    fields = []

    if tags:
        event_tags = event.tags if event else group.get_latest_event().tags

        for key, value in event_tags:
            std_key = tagstore.get_standardized_key(key)
            if std_key not in tags:
                continue

            labeled_value = tagstore.get_tag_value_label(key, value)
            fields.append(
                {
                    'title': std_key.encode('utf-8'),
                    'value': labeled_value.encode('utf-8'),
                    'short': True,
                }
            )

    if actions:
        action_texts = filter(None, [build_action_text(group, identity, a) for a in actions])
        text += '\n' + '\n'.join(action_texts)

        color = ACTIONED_ISSUE_COLOR
        payload_actions = []

    ts = group.last_seen

    if event:
        event_ts = event.datetime
        ts = max(ts, event_ts)

    footer = u'{}'.format(group.qualified_short_id)

    if rules:
        footer += u' via {}'.format(rules[0].label)

        if len(rules) > 1:
            footer += u' (+{} other)'.format(len(rules) - 1)

    return {
        'fallback': u'[{}] {}'.format(group.project.slug, group.title),
        'title': build_attachment_title(group, event),
        'title_link': group.get_absolute_url(params={'referrer': 'slack'}),
        'text': text,
        'fields': fields,
        'mrkdwn_in': ['text'],
        'callback_id': json.dumps({'issue': group.id}),
        'footer_icon': logo_url,
        'footer': footer,
        'ts': to_timestamp(ts),
        'color': color,
        'actions': payload_actions,
    }
Exemplo n.º 44
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.title.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('custom_message', project):
            fields.append({
                'title': 'Custom message',
                'value': self.get_option('custom_message', project),
                'short': False,
            })

        if self.get_option('include_rules', project):
            rules = []
            for rule in notification.rules:
                rule_link = '/%s/%s/settings/alerts/rules/%s/' % (
                    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))

            if rules:
                value = u', '.join(u'<{} | {}>'.format(*r) for r in rules)

                fields.append(
                    {
                        'title': 'Triggered By',
                        'value': value.encode('utf-8'),
                        '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 = tagstore.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': group.get_absolute_url(params={'referrer': 'slack'}),
                    '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)