def get(self, request, sentry_app):
        """
        :qparam float since
        :qparam float until
        :qparam resolution - optional
        """

        views = tsdb.get_range(model=tsdb.models.sentry_app_viewed,
                               keys=[sentry_app.id],
                               **self._parse_args(request))[sentry_app.id]

        component_interactions = tsdb.get_range(
            model=tsdb.models.sentry_app_component_interacted,
            keys=[
                get_component_interaction_key(sentry_app, component.type)
                for component in sentry_app.components.all()
            ],
            **self._parse_args(request),
        )

        return Response({
            "views": views,
            "componentInteractions":
            {k.split(":")[1]: v
             for k, v in component_interactions.items()},
        })
Exemplo n.º 2
0
    def get_attrs(self, item_list, user):
        attrs = super(StreamGroupSerializer, self).get_attrs(item_list, user)

        if self.stats_period:
            # we need to compute stats at 1d (1h resolution), and 14d
            group_ids = [g.id for g in item_list]

            segments, interval = self.STATS_PERIOD_CHOICES[self.stats_period]
            now = timezone.now()
            query_params = {
                'start': now - ((segments - 1) * interval),
                'end': now,
                'rollup': int(interval.total_seconds()),
            }
            try:
                stats = tsdb.get_range(
                    model=tsdb.models.group,
                    keys=group_ids,
                    environment_id=self.environment_id_func(),
                    **query_params)
            except Environment.DoesNotExist:
                stats = {
                    key: tsdb.make_series(0, **query_params)
                    for key in group_ids
                }

            for item in item_list:
                attrs[item].update({
                    'stats': stats[item.id],
                })

        return attrs
Exemplo n.º 3
0
    def get(self, request, project, key_id):
        try:
            key = ProjectKey.objects.get(
                project=project,
                public_key=key_id,
                roles=ProjectKey.roles.store,
            )
        except ProjectKey.DoesNotExist:
            raise ResourceDoesNotExist

        stat_args = self._parse_args(request)

        stats = OrderedDict()
        for model, name in (
            (tsdb.models.key_total_received,
             'total'), (tsdb.models.key_total_blacklisted, 'filtered'),
            (tsdb.models.key_total_rejected, 'dropped'),
        ):
            result = tsdb.get_range(model=model, keys=[key.id], **stat_args)[key.id]
            for ts, count in result:
                stats.setdefault(int(ts), {})[name] = count

        return Response(
            [
                {
                    'ts': ts,
                    'total': data['total'],
                    'dropped': data['dropped'],
                    'filtered': data['filtered'],
                    'accepted': data['total'] - data['dropped'] - data['filtered'],
                } for ts, data in six.iteritems(stats)
            ]
        )
Exemplo n.º 4
0
    def get(self, request, project, key_id):
        try:
            key = ProjectKey.objects.get(
                project=project,
                public_key=key_id,
                roles=F('roles').bitor(ProjectKey.roles.store),
            )
        except ProjectKey.DoesNotExist:
            raise ResourceDoesNotExist

        stat_args = self._parse_args(request)

        stats = OrderedDict()
        for model, name in (
            (tsdb.models.key_total_received, 'total'),
            (tsdb.models.key_total_blacklisted, 'filtered'),
            (tsdb.models.key_total_rejected, 'dropped'),
        ):
            result = tsdb.get_range(model=model, keys=[key.id],
                                    **stat_args)[key.id]
            for ts, count in result:
                stats.setdefault(int(ts), {})[name] = count

        return Response([{
            'ts':
            ts,
            'total':
            data['total'],
            'dropped':
            data['dropped'],
            'filtered':
            data['filtered'],
            'accepted':
            data['total'] - data['dropped'] - data['filtered'],
        } for ts, data in six.iteritems(stats)])
    def get(self, request, project, hook_id):
        try:
            hook = ServiceHook.objects.get(
                project_id=project.id,
                guid=hook_id,
            )
        except ServiceHook.DoesNotExist:
            raise ResourceDoesNotExist

        stat_args = self._parse_args(request)

        stats = OrderedDict()
        for model, name in (
            (tsdb.models.servicehook_fired, 'total'),
        ):
            result = tsdb.get_range(model=model, keys=[hook.id], **stat_args)[hook.id]
            for ts, count in result:
                stats.setdefault(int(ts), {})[name] = count

        return self.respond([
            {
                'ts': ts,
                'total': data['total'],
            } for ts, data in six.iteritems(stats)
        ])
Exemplo n.º 6
0
    def get(self, request, team):
        """
        Retrieve Event Counts for a Team
        ````````````````````````````````

        .. caution::
           This endpoint may change in the future without notice.

        Return a set of points representing a normalized timestamp and the
        number of events seen in the period.

        Query ranges are limited to Sentry's configured time-series
        resolutions.

        :pparam string organization_slug: the slug of the organization.
        :pparam string team_slug: the slug of the team.
        :qparam string stat: the name of the stat to query (``"received"``,
                             ``"rejected"``)
        :qparam timestamp since: a timestamp to set the start of the query
                                 in seconds since UNIX epoch.
        :qparam timestamp until: a timestamp to set the end of the query
                                 in seconds since UNIX epoch.
        :qparam string resolution: an explicit resolution to search
                                   for (eg: ``10s``).  This should not be
                                   used unless you are familiar with Sentry's
                                   internals as it's restricted to pre-defined
                                   values.
        :auth: required
        """
        try:
            environment_id = self._get_environment_id_from_request(
                request,
                team.organization_id,
            )
        except Environment.DoesNotExist:
            raise ResourceDoesNotExist

        projects = Project.objects.get_for_user(
            team=team,
            user=request.user,
        )

        if not projects:
            return Response([])

        data = list(
            tsdb.get_range(
                model=tsdb.models.project,
                keys=[p.id for p in projects],
                **self._parse_args(request, environment_id)
            ).values()
        )

        summarized = []
        for n in range(len(data[0])):
            total = sum(d[n][1] for d in data)
            summarized.append((data[0][n][0], total))

        return Response(summarized)
Exemplo n.º 7
0
    def get(self, request, project):
        """
        Retrieve Event Counts for a Project
        ```````````````````````````````````

        .. caution::
           This endpoint may change in the future without notice.

        Return a set of points representing a normalized timestamp and the
        number of events seen in the period.

        Query ranges are limited to Sentry's configured time-series
        resolutions.

        :pparam string organization_slug: the slug of the organization.
        :pparam string project_slug: the slug of the project.
        :qparam string stat: the name of the stat to query (``"received"``,
                             ``"rejected"``, ``"blacklisted"``, ``generated``)
        :qparam timestamp since: a timestamp to set the start of the query
                                 in seconds since UNIX epoch.
        :qparam timestamp until: a timestamp to set the end of the query
                                 in seconds since UNIX epoch.
        :qparam string resolution: an explicit resolution to search
                                   for (eg: ``10s``).  This should not be
                                   used unless you are familiar with Sentry's
                                   internals as it's restricted to pre-defined
                                   values.
        :auth: required
        """
        stat = request.GET.get('stat', 'received')
        query_kwargs = {}
        if stat == 'received':
            stat_model = tsdb.models.project_total_received
        elif stat == 'rejected':
            stat_model = tsdb.models.project_total_rejected
        elif stat == 'blacklisted':
            stat_model = tsdb.models.project_total_blacklisted
        elif stat == 'generated':
            stat_model = tsdb.models.project
            try:
                query_kwargs['environment_id'] = self._get_environment_id_from_request(
                    request,
                    project.organization_id,
                )
            except Environment.DoesNotExist:
                raise ResourceDoesNotExist
        elif stat == 'forwarded':
            stat_model = tsdb.models.project_total_forwarded
        else:
            try:
                stat_model = FILTER_STAT_KEYS_TO_VALUES[stat]
            except KeyError:
                raise ValueError('Invalid stat: %s' % stat)

        data = tsdb.get_range(
            model=stat_model, keys=[project.id], **self._parse_args(request, **query_kwargs)
        )[project.id]

        return Response(data)
Exemplo n.º 8
0
    def get(self, request):
        key = request.GET["key"]

        data = tsdb.get_range(model=tsdb.models.internal,
                              keys=[key],
                              **self._parse_args(request))[key]

        return Response(data)
Exemplo n.º 9
0
    def get(self, request):
        key = request.GET['key']

        data = tsdb.get_range(
            model=tsdb.models.internal, keys=[key], **self._parse_args(request)
        )[key]

        return Response(data)
Exemplo n.º 10
0
    def get(self, request, group):
        data = tsdb.get_range(
            model=tsdb.models.group,
            keys=[group.id],
            **self._parse_args(request)
        )[group.id]

        return Response(data)
Exemplo n.º 11
0
    def get(self, request, project):
        """
        Retrieve Event Counts for a Project
        ```````````````````````````````````

        .. caution::
           This endpoint may change in the future without notice.

        Return a set of points representing a normalized timestamp and the
        number of events seen in the period.

        Query ranges are limited to Sentry's configured time-series
        resolutions.

        :pparam string organization_slug: the slug of the organization.
        :pparam string project_slug: the slug of the project.
        :qparam string stat: the name of the stat to query (``"received"``,
                             ``"rejected"``, ``"blacklisted"``, ``generated``)
        :qparam timestamp since: a timestamp to set the start of the query
                                 in seconds since UNIX epoch.
        :qparam timestamp until: a timestamp to set the end of the query
                                 in seconds since UNIX epoch.
        :qparam string resolution: an explicit resolution to search
                                   for (one of ``10s``, ``1h``, and ``1d``)
        :auth: required
        """
        stat = request.GET.get('stat', 'received')
        query_kwargs = {}
        if stat == 'received':
            stat_model = tsdb.models.project_total_received
        elif stat == 'rejected':
            stat_model = tsdb.models.project_total_rejected
        elif stat == 'blacklisted':
            stat_model = tsdb.models.project_total_blacklisted
        elif stat == 'generated':
            stat_model = tsdb.models.project
            try:
                query_kwargs[
                    'environment_id'] = self._get_environment_id_from_request(
                        request,
                        project.organization_id,
                    )
            except Environment.DoesNotExist:
                raise ResourceDoesNotExist
        elif stat == 'forwarded':
            stat_model = tsdb.models.project_total_forwarded
        else:
            try:
                stat_model = FILTER_STAT_KEYS_TO_VALUES[stat]
            except KeyError:
                raise ValueError('Invalid stat: %s' % stat)

        data = tsdb.get_range(model=stat_model,
                              keys=[project.id],
                              **self._parse_args(request,
                                                 **query_kwargs))[project.id]

        return Response(data)
    def get(self, request, team):
        """
        Retrieve Event Counts for a Team
        ````````````````````````````````

        .. caution::
           This endpoint may change in the future without notice.

        Return a set of points representing a normalized timestamp and the
        number of events seen in the period.

        Query ranges are limited to Sentry's configured time-series
        resolutions.

        :pparam string organization_slug: the slug of the organization.
        :pparam string team_slug: the slug of the team.
        :qparam string stat: the name of the stat to query (``"received"``,
                             ``"rejected"``)
        :qparam timestamp since: a timestamp to set the start of the query
                                 in seconds since UNIX epoch.
        :qparam timestamp until: a timestamp to set the end of the query
                                 in seconds since UNIX epoch.
        :qparam string resolution: an explicit resolution to search
                                   for (eg: ``10s``).  This should not be
                                   used unless you are familiar with Sentry's
                                   internals as it's restricted to pre-defined
                                   values.
        :auth: required
        """
        try:
            environment_id = self._get_environment_id_from_request(
                request,
                team.organization_id,
            )
        except Environment.DoesNotExist:
            raise ResourceDoesNotExist

        projects = Project.objects.get_for_user(
            team=team,
            user=request.user,
        )

        if not projects:
            return Response([])

        data = list(
            tsdb.get_range(model=tsdb.models.project,
                           keys=[p.id for p in projects],
                           **self._parse_args(request,
                                              environment_id)).values())

        summarized = []
        for n in range(len(data[0])):
            total = sum(d[n][1] for d in data)
            summarized.append((data[0][n][0], total))

        return Response(summarized)
Exemplo n.º 13
0
def with_event_counts(project_list):
    end = timezone.now()
    start = end - datetime.timedelta(days=1)

    tsdb_results = tsdb.get_range(
        model=tsdb.models.project, keys=[p.id for p in project_list], start=start, end=end
    )

    for project in project_list:
        yield project, sum(t[1] for t in tsdb_results[project.id])
Exemplo n.º 14
0
    def get_attrs(self, item_list, user):
        project_ids = [i.id for i in item_list]
        if user.is_authenticated() and item_list:
            bookmarks = set(
                ProjectBookmark.objects.filter(
                    user=user,
                    project_id__in=project_ids,
                ).values_list('project_id', flat=True))
            user_options = {
                (u.project_id, u.key): u.value
                for u in UserOption.objects.filter(
                    Q(user=user, project__in=item_list, key='mail:alert')
                    | Q(user=user,
                        key='subscribe_by_default',
                        project__isnull=True))
            }
            default_subscribe = (user_options.get('subscribe_by_default',
                                                  '1') == '1')
        else:
            bookmarks = set()
            user_options = {}
            default_subscribe = False

        if self.stats_period:
            # we need to compute stats at 1d (1h resolution), and 14d
            project_ids = [o.id for o in item_list]

            segments, interval = STATS_PERIOD_CHOICES[self.stats_period]
            now = timezone.now()
            stats = tsdb.get_range(
                model=tsdb.models.project,
                keys=project_ids,
                end=now,
                start=now - ((segments - 1) * interval),
                rollup=int(interval.total_seconds()),
                environment_id=self.environment_id,
            )
        else:
            stats = None

        result = self.get_access_by_project(item_list, user)
        for item in item_list:
            result[item].update({
                'is_bookmarked':
                item.id in bookmarks,
                'is_subscribed':
                bool(
                    user_options.get(
                        (item.id, 'mail:alert'),
                        default_subscribe,
                    )),
            })
            if stats:
                result[item]['stats'] = stats[item.id]
        return result
Exemplo n.º 15
0
    def attach_metadata(self, objects, request=None):
        from sentry.templatetags.sentry_plugins import handle_before_events

        attach_foreignkey(objects, Group.project, ['team'])

        GroupMeta.objects.populate_cache(objects)

        if request and objects:
            handle_before_events(request, objects)

        if request and request.user.is_authenticated() and objects:
            bookmarks = set(
                GroupBookmark.objects.filter(
                    user=request.user,
                    group__in=objects,
                ).values_list('group_id', flat=True))
            seen_groups = dict(
                GroupSeen.objects.filter(
                    user=request.user,
                    group__in=objects,
                ).values_list('group_id', 'last_seen'))
        else:
            bookmarks = set()
            seen_groups = {}

        if objects:
            end = timezone.now()
            start = end - timedelta(days=1)

            historical_data = tsdb.get_range(
                model=tsdb.models.group,
                keys=[g.id for g in objects],
                start=start,
                end=end,
            )
        else:
            historical_data = {}

        user_tagkeys = GroupTagKey.objects.filter(
            group_id__in=[o.id for o in objects],
            key='sentry:user',
        )
        user_counts = {}
        for user_tagkey in user_tagkeys:
            user_counts[user_tagkey.group_id] = user_tagkey.values_seen

        for g in objects:
            g.is_bookmarked = g.pk in bookmarks
            g.historical_data = [x[1] for x in historical_data.get(g.id, [])]
            active_date = g.active_at or g.first_seen
            g.has_seen = seen_groups.get(g.id, active_date) > active_date
            g.annotations = [{
                'label': 'users',
                'count': user_counts.get(g.id, 0),
            }]
Exemplo n.º 16
0
    def get_attrs(self, item_list, user):
        project_ids = [i.id for i in item_list]
        if user.is_authenticated() and item_list:
            bookmarks = set(
                ProjectBookmark.objects.filter(
                    user=user,
                    project_id__in=project_ids,
                ).values_list('project_id', flat=True)
            )
            user_options = {
                (u.project_id, u.key): u.value
                for u in UserOption.objects.filter(
                    Q(user=user, project__in=item_list, key='mail:alert') |
                    Q(user=user, key='subscribe_by_default', project__isnull=True)
                )
            }
            default_subscribe = (user_options.get(
                'subscribe_by_default', '1') == '1')
        else:
            bookmarks = set()
            user_options = {}
            default_subscribe = False

        if self.stats_period:
            # we need to compute stats at 1d (1h resolution), and 14d
            project_ids = [o.id for o in item_list]

            segments, interval = STATS_PERIOD_CHOICES[self.stats_period]
            now = timezone.now()
            stats = tsdb.get_range(
                model=tsdb.models.project_total_received,
                keys=project_ids,
                end=now,
                start=now - ((segments - 1) * interval),
                rollup=int(interval.total_seconds()),
            )
        else:
            stats = None

        result = {}
        for item in item_list:
            result[item] = {
                'is_bookmarked': item.id in bookmarks,
                'is_subscribed':
                bool(user_options.get(
                    (item.id, 'mail:alert'),
                    default_subscribe,
                )),
            }
            if stats:
                result[item]['stats'] = stats[item.id]
        return result
Exemplo n.º 17
0
def with_event_counts(project_list):
    end = timezone.now()
    start = end - datetime.timedelta(days=1)

    tsdb_results = tsdb.get_range(
        model=tsdb.models.project,
        keys=[p.id for p in project_list],
        start=start,
        end=end,
    )

    for project in project_list:
        yield project, sum(t[1] for t in tsdb_results[project.id])
Exemplo n.º 18
0
    def get(self, request, group):
        try:
            environment_id = self._get_environment_id_from_request(
                request, group.project.organization_id)
        except Environment.DoesNotExist:
            raise ResourceDoesNotExist

        data = tsdb.get_range(model=tsdb.models.group,
                              keys=[group.id],
                              **self._parse_args(request,
                                                 environment_id))[group.id]

        return Response(data)
Exemplo n.º 19
0
    def get(self, request, project):
        """
        Retrieve Event Counts for a Project
        ```````````````````````````````````

        .. caution::
           This endpoint may change in the future without notice.

        Return a set of points representing a normalized timestamp and the
        number of events seen in the period.

        Query ranges are limited to Sentry's configured time-series
        resolutions.

        :pparam string organization_slug: the slug of the organization.
        :pparam string project_slug: the slug of the project.
        :qparam string stat: the name of the stat to query (``"received"``,
                             ``"rejected"``, ``"blacklisted"``, ``generated``)
        :qparam timestamp since: a timestamp to set the start of the query
                                 in seconds since UNIX epoch.
        :qparam timestamp until: a timestamp to set the end of the query
                                 in seconds since UNIX epoch.
        :qparam string resolution: an explicit resolution to search
                                   for (eg: ``10s``).  This should not be
                                   used unless you are familiar with Sentry's
                                   internals as it's restricted to pre-defined
                                   values.
        :auth: required
        """
        stat = request.GET.get('stat', 'received')
        if stat == 'received':
            stat_model = tsdb.models.project_total_received
        elif stat == 'rejected':
            stat_model = tsdb.models.project_total_rejected
        elif stat == 'blacklisted':
            stat_model = tsdb.models.project_total_blacklisted
        elif stat == 'generated':
            stat_model = tsdb.models.project
        elif stat == 'forwarded':
            stat_model = tsdb.models.project_total_forwarded
        else:
            try:
                stat_model = FILTER_STAT_KEYS_TO_VALUES[stat]
            except KeyError:
                raise ValueError('Invalid stat: %s' % stat)

        data = tsdb.get_range(model=stat_model,
                              keys=[project.id],
                              **self._parse_args(request))[project.id]

        return Response(data)
Exemplo n.º 20
0
    def query_tsdb(self, group_ids, query_params, **kwargs):
        try:
            environment = self.environment_func()
        except Environment.DoesNotExist:
            stats = {key: tsdb.make_series(0, **query_params) for key in group_ids}
        else:
            stats = tsdb.get_range(
                model=tsdb.models.group,
                keys=group_ids,
                environment_ids=environment and [environment.id],
                **query_params,
            )

        return stats
Exemplo n.º 21
0
    def query_tsdb(self, group_ids, query_params):
        try:
            environment = self.environment_func()
        except Environment.DoesNotExist:
            stats = {key: tsdb.make_series(0, **query_params) for key in group_ids}
        else:
            stats = tsdb.get_range(
                model=tsdb.models.group,
                keys=group_ids,
                environment_ids=environment and [environment.id],
                **query_params
            )

        return stats
Exemplo n.º 22
0
    def get(self, request, group):
        try:
            environment_id = self._get_environment_id_from_request(
                request,
                group.project.organization_id,
            )
        except Environment.DoesNotExist:
            raise ResourceDoesNotExist

        data = tsdb.get_range(
            model=tsdb.models.group, keys=[group.id], **self._parse_args(
                request,
                environment_id,
            )
        )[group.id]

        return Response(data)
Exemplo n.º 23
0
    def get(self, request, project, key_id):
        try:
            key = ProjectKey.objects.get(
                project=project,
                public_key=key_id,
                roles=F('roles').bitor(ProjectKey.roles.store),
            )
        except ProjectKey.DoesNotExist:
            raise ResourceDoesNotExist

        try:
            stat_args = self._parse_args(request)
        except ValueError:
            return Response({'detail': 'Invalid request data'}, status=400)

        stats = OrderedDict()
        for model, name in (
            (tsdb.models.key_total_received, 'total'),
            (tsdb.models.key_total_blacklisted, 'filtered'),
            (tsdb.models.key_total_rejected, 'dropped'),
        ):
            # XXX (alex, 08/05/19) key stats were being stored under either key_id or str(key_id)
            # so merge both of those back into one stats result.
            result = tsdb.get_range(model=model,
                                    keys=[key.id,
                                          six.text_type(key.id)],
                                    **stat_args)
            for key_id, points in six.iteritems(result):
                for ts, count in points:
                    bucket = stats.setdefault(int(ts), {})
                    bucket.setdefault(name, 0)
                    bucket[name] += count

        return Response([{
            'ts':
            ts,
            'total':
            data['total'],
            'dropped':
            data['dropped'],
            'filtered':
            data['filtered'],
            'accepted':
            data['total'] - data['dropped'] - data['filtered'],
        } for ts, data in six.iteritems(stats)])
Exemplo n.º 24
0
    def get(self, request: Request, project, key_id) -> Response:
        try:
            key = ProjectKey.objects.get(project=project,
                                         public_key=key_id,
                                         roles=F("roles").bitor(
                                             ProjectKey.roles.store))
        except ProjectKey.DoesNotExist:
            raise ResourceDoesNotExist

        try:
            stat_args = self._parse_args(request)
        except ValueError:
            return Response({"detail": "Invalid request data"}, status=400)

        stats = OrderedDict()
        for model, name in (
            (tsdb.models.key_total_received, "total"),
            (tsdb.models.key_total_blacklisted, "filtered"),
            (tsdb.models.key_total_rejected, "dropped"),
        ):
            # XXX (alex, 08/05/19) key stats were being stored under either key_id or str(key_id)
            # so merge both of those back into one stats result.
            result = tsdb.get_range(model=model,
                                    keys=[key.id, str(key.id)],
                                    **stat_args)
            for key_id, points in result.items():
                for ts, count in points:
                    bucket = stats.setdefault(int(ts), {})
                    bucket.setdefault(name, 0)
                    bucket[name] += count

        return Response([{
            "ts":
            ts,
            "total":
            data["total"],
            "dropped":
            data["dropped"],
            "filtered":
            data["filtered"],
            "accepted":
            data["total"] - data["dropped"] - data["filtered"],
        } for ts, data in stats.items()])
Exemplo n.º 25
0
    def get(self, request, project, key_id):
        try:
            key = ProjectKey.objects.get(
                project=project,
                public_key=key_id,
                roles=F('roles').bitor(ProjectKey.roles.store),
            )
        except ProjectKey.DoesNotExist:
            raise ResourceDoesNotExist

        stat_args = self._parse_args(request)

        stats = OrderedDict()
        for model, name in (
            (tsdb.models.key_total_received,
             'total'), (tsdb.models.key_total_blacklisted, 'filtered'),
            (tsdb.models.key_total_rejected, 'dropped'),
        ):
            # XXX (alex, 08/05/19) key stats were being stored under either key_id or str(key_id)
            # so merge both of those back into one stats result.
            result = tsdb.get_range(model=model, keys=[key.id, six.text_type(key.id)], **stat_args)
            for key_id, points in six.iteritems(result):
                for ts, count in points:
                    bucket = stats.setdefault(int(ts), {})
                    bucket.setdefault(name, 0)
                    bucket[name] += count

        return Response(
            [
                {
                    'ts': ts,
                    'total': data['total'],
                    'dropped': data['dropped'],
                    'filtered': data['filtered'],
                    'accepted': data['total'] - data['dropped'] - data['filtered'],
                } for ts, data in six.iteritems(stats)
            ]
        )
Exemplo n.º 26
0
    def get_attrs(self, item_list, user):
        attrs = super(StreamGroupSerializer, self).get_attrs(item_list, user)

        if self.stats_period:
            # we need to compute stats at 1d (1h resolution), and 14d
            group_ids = [g.id for g in item_list]

            segments, interval = self.STATS_PERIOD_CHOICES[self.stats_period]
            now = timezone.now()
            stats = tsdb.get_range(
                model=tsdb.models.group,
                keys=group_ids,
                end=now,
                start=now - ((segments - 1) * interval),
                rollup=int(interval.total_seconds()),
            )

            for item in item_list:
                attrs[item].update({
                    'stats': stats[item.id],
                })

        return attrs
Exemplo n.º 27
0
    def get_attrs(self, item_list, user):
        attrs = super(StreamGroupSerializer, self).get_attrs(item_list, user)

        if self.stats_period:
            # we need to compute stats at 1d (1h resolution), and 14d
            group_ids = [g.id for g in item_list]

            segments, interval = self.STATS_PERIOD_CHOICES[self.stats_period]
            now = timezone.now()
            stats = tsdb.get_range(
                model=tsdb.models.group,
                keys=group_ids,
                end=now,
                start=now - ((segments - 1) * interval),
                rollup=int(interval.total_seconds()),
            )

            for item in item_list:
                attrs[item].update({
                    'stats': stats[item.id],
                })

        return attrs
Exemplo n.º 28
0
    def get_attrs(self, item_list, user):
        project_ids = [i.id for i in item_list]
        if user.is_authenticated() and item_list:
            bookmarks = set(
                ProjectBookmark.objects.filter(
                    user=user,
                    project_id__in=project_ids).values_list("project_id",
                                                            flat=True))
            user_options = {
                (u.project_id, u.key): u.value
                for u in UserOption.objects.filter(
                    Q(user=user, project__in=item_list, key="mail:alert")
                    | Q(user=user,
                        key="subscribe_by_default",
                        project__isnull=True))
            }
            default_subscribe = user_options.get("subscribe_by_default",
                                                 "1") == "1"
        else:
            bookmarks = set()
            user_options = {}
            default_subscribe = False

        if self.stats_period:
            # we need to compute stats at 1d (1h resolution), and 14d
            project_ids = [o.id for o in item_list]

            segments, interval = STATS_PERIOD_CHOICES[self.stats_period]
            now = timezone.now()
            stats = tsdb.get_range(
                model=tsdb.models.project,
                keys=project_ids,
                end=now,
                start=now - ((segments - 1) * interval),
                rollup=int(interval.total_seconds()),
                environment_ids=self.environment_id and [self.environment_id],
            )
        else:
            stats = None

        avatars = {
            a.project_id: a
            for a in ProjectAvatar.objects.filter(project__in=item_list)
        }
        project_ids = [i.id for i in item_list]
        platforms = ProjectPlatform.objects.filter(
            project_id__in=project_ids).values_list("project_id", "platform")
        platforms_by_project = defaultdict(list)
        for project_id, platform in platforms:
            platforms_by_project[project_id].append(platform)

        result = self.get_access_by_project(item_list, user)
        for item in item_list:
            result[item].update({
                "is_bookmarked":
                item.id in bookmarks,
                "is_subscribed":
                bool(
                    user_options.get((item.id, "mail:alert"),
                                     default_subscribe)),
                "avatar":
                avatars.get(item.id),
                "platforms":
                platforms_by_project[item.id],
            })
            if stats:
                result[item]["stats"] = stats[item.id]
        return result
Exemplo n.º 29
0
    def get(self, request, group):
        """
        Retrieve an Issue
        `````````````````

        Return details on an individual issue. This returns the basic stats for
        the issue (title, last seen, first seen), some overall numbers (number
        of comments, user reports) as well as the summarized event data.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """
        # TODO(dcramer): handle unauthenticated/public response
        data = serialize(group, request.user)

        # TODO: these probably should be another endpoint
        activity = self._get_activity(request, group, num=100)
        seen_by = self._get_seen_by(request, group)

        # find first seen release
        if group.first_release is None:
            try:
                first_release = GroupTagValue.objects.filter(
                    group=group,
                    key__in=('sentry:release', 'release'),
                ).order_by('first_seen')[0]
            except IndexError:
                first_release = None
            else:
                first_release = first_release.value
        else:
            first_release = group.first_release.version

        if first_release is not None:
            # find last seen release
            try:
                last_release = GroupTagValue.objects.filter(
                    group=group,
                    key__in=('sentry:release', 'release'),
                ).order_by('-last_seen')[0]
            except IndexError:
                last_release = None
            else:
                last_release = last_release.value
        else:
            last_release = None

        action_list = self._get_actions(request, group)

        now = timezone.now()
        hourly_stats = tsdb.rollup(
            tsdb.get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=1),
            ), 3600)[group.id]
        daily_stats = tsdb.rollup(
            tsdb.get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=30),
            ), 3600 * 24)[group.id]

        if first_release:
            first_release = self._get_release_info(request, group,
                                                   first_release)
        if last_release:
            last_release = self._get_release_info(request, group, last_release)

        tags = list(GroupTagKey.objects.filter(group=group, )[:100])

        participants = list(
            User.objects.filter(
                groupsubscription__is_active=True,
                groupsubscription__group=group,
            ))

        data.update({
            'firstRelease':
            first_release,
            'lastRelease':
            last_release,
            'activity':
            serialize(activity, request.user),
            'seenBy':
            seen_by,
            'participants':
            serialize(participants, request.user),
            'pluginActions':
            action_list,
            'pluginIssues':
            self._get_available_issue_plugins(request, group),
            'pluginContexts':
            self._get_context_plugins(request, group),
            'userReportCount':
            UserReport.objects.filter(group=group).count(),
            'tags':
            sorted(serialize(tags, request.user), key=lambda x: x['name']),
            'stats': {
                '24h': hourly_stats,
                '30d': daily_stats,
            }
        })

        return Response(data)
Exemplo n.º 30
0
    def get(self, request, group):
        """
        Retrieve an Issue
        `````````````````

        Return details on an individual issue. This returns the basic stats for
        the issue (title, last seen, first seen), some overall numbers (number
        of comments, user reports) as well as the summarized event data.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """
        # TODO(dcramer): handle unauthenticated/public response
        data = serialize(group, request.user)

        # TODO: these probably should be another endpoint
        activity = self._get_activity(request, group, num=100)
        seen_by = self._get_seen_by(request, group)

        first_release = group.get_first_release()

        if first_release is not None:
            last_release = group.get_last_release()
        else:
            last_release = None

        action_list = self._get_actions(request, group)

        now = timezone.now()
        hourly_stats = tsdb.rollup(
            tsdb.get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=1),
            ), 3600)[group.id]
        daily_stats = tsdb.rollup(
            tsdb.get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=30),
            ), 3600 * 24)[group.id]

        if first_release:
            first_release = self._get_release_info(request, group,
                                                   first_release)
        if last_release:
            last_release = self._get_release_info(request, group, last_release)

        try:
            environment_id = self._get_environment_id_from_request(
                request, group.project.organization_id)
        except Environment.DoesNotExist:
            tags = []
        else:
            tags = tagstore.get_group_tag_keys(group.project_id,
                                               group.id,
                                               environment_id,
                                               limit=100)

        participants = list(
            User.objects.filter(
                groupsubscription__is_active=True,
                groupsubscription__group=group,
            ))

        data.update({
            'firstRelease':
            first_release,
            'lastRelease':
            last_release,
            'activity':
            serialize(activity, request.user),
            'seenBy':
            seen_by,
            'participants':
            serialize(participants, request.user),
            'pluginActions':
            action_list,
            'pluginIssues':
            self._get_available_issue_plugins(request, group),
            'pluginContexts':
            self._get_context_plugins(request, group),
            'userReportCount':
            UserReport.objects.filter(group=group).count(),
            'tags':
            sorted(serialize(tags, request.user), key=lambda x: x['name']),
            'stats': {
                '24h': hourly_stats,
                '30d': daily_stats,
            }
        })

        return Response(data)
Exemplo n.º 31
0
    def get(self, request, organization):
        """
        Retrieve Event Counts for an Organization
        `````````````````````````````````````````

        .. caution::
           This endpoint may change in the future without notice.

        Return a set of points representing a normalized timestamp and the
        number of events seen in the period.

        :pparam string organization_slug: the slug of the organization for
                                          which the stats should be
                                          retrieved.
        :qparam string stat: the name of the stat to query (``"received"``,
                             ``"rejected"``, ``"blacklisted"``)
        :qparam timestamp since: a timestamp to set the start of the query
                                 in seconds since UNIX epoch.
        :qparam timestamp until: a timestamp to set the end of the query
                                 in seconds since UNIX epoch.
        :qparam string resolution: an explicit resolution to search
                                   for (one of ``10s``, ``1h``, and ``1d``)
        :auth: required
        """
        group = request.GET.get("group", "organization")
        if group == "organization":
            keys = [organization.id]
        elif group == "project":
            team_list = Team.objects.get_for_user(organization=organization,
                                                  user=request.user)

            project_ids = request.GET.getlist("projectID")
            if not project_ids:
                project_list = []
                for team in team_list:
                    project_list.extend(
                        Project.objects.get_for_user(team=team,
                                                     user=request.user))
            else:
                project_list = Project.objects.filter(teams__in=team_list,
                                                      id__in=project_ids)
            keys = list({p.id for p in project_list})
        else:
            raise ValueError("Invalid group: %s" % group)

        if "id" in request.GET:
            id_filter_set = frozenset(map(int, request.GET.getlist("id")))
            keys = [k for k in keys if k in id_filter_set]

        if not keys:
            return Response([])

        stat_model = None
        stat = request.GET.get("stat", "received")
        query_kwargs = {}
        if stat == "received":
            if group == "project":
                stat_model = tsdb.models.project_total_received
            else:
                stat_model = tsdb.models.organization_total_received
        elif stat == "rejected":
            if group == "project":
                stat_model = tsdb.models.project_total_rejected
            else:
                stat_model = tsdb.models.organization_total_rejected
        elif stat == "blacklisted":
            if group == "project":
                stat_model = tsdb.models.project_total_blacklisted
            else:
                stat_model = tsdb.models.organization_total_blacklisted
        elif stat == "generated":
            if group == "project":
                stat_model = tsdb.models.project
                try:
                    query_kwargs[
                        "environment_id"] = self._get_environment_id_from_request(
                            request, organization.id)
                except Environment.DoesNotExist:
                    raise ResourceDoesNotExist

        if stat_model is None:
            raise ValueError("Invalid group: %s, stat: %s" % (group, stat))
        data = tsdb.get_range(model=stat_model,
                              keys=keys,
                              **self._parse_args(request, **query_kwargs))

        if group == "organization":
            data = data[organization.id]

        return Response(data)
Exemplo n.º 32
0
    def attach_metadata(self, objects, request=None):
        from sentry.templatetags.sentry_plugins import handle_before_events

        attach_foreignkey(objects, Group.project, ['team'])

        GroupMeta.objects.populate_cache(objects)

        if request and objects:
            handle_before_events(request, objects)

        if request and request.user.is_authenticated() and objects:
            bookmarks = set(
                GroupBookmark.objects.filter(
                    user=request.user,
                    group__in=objects,
                ).values_list('group_id', flat=True))
            seen_groups = dict(
                GroupSeen.objects.filter(
                    user=request.user,
                    group__in=objects,
                ).values_list('group_id', 'last_seen'))
        else:
            bookmarks = set()
            seen_groups = {}

        if objects:
            end = timezone.now()
            start = end - timedelta(days=1)

            historical_data = tsdb.get_range(
                model=tsdb.models.group,
                keys=[g.id for g in objects],
                start=start,
                end=end,
            )
        else:
            historical_data = {}

        project_list = set(o.project for o in objects)
        tag_keys = set(['sentry:user'])
        project_annotations = {}
        for project in project_list:
            enabled_annotations = ProjectOption.objects.get_value(
                project, 'annotations', ['sentry:user'])
            project_annotations[project] = enabled_annotations
            tag_keys.update(enabled_annotations)

        annotation_counts = defaultdict(dict)
        annotation_results = GroupTagKey.objects.filter(
            group__in=objects,
            key__in=tag_keys,
        ).values_list('key', 'group', 'values_seen')
        for key, group_id, values_seen in annotation_results:
            annotation_counts[key][group_id] = values_seen

        for g in objects:
            g.is_bookmarked = g.pk in bookmarks
            g.historical_data = [x[1] for x in historical_data.get(g.id, [])]
            active_date = g.active_at or g.first_seen
            g.has_seen = seen_groups.get(g.id, active_date) > active_date
            g.annotations = []
            for key in sorted(tag_keys):
                if key in project_annotations[project]:
                    label = TAG_LABELS.get(key, key.replace('_',
                                                            ' ')).lower() + 's'
                    try:
                        value = annotation_counts[key].get(g.id, 0)
                    except KeyError:
                        value = 0
                    g.annotations.append({
                        'label': label,
                        'count': value,
                    })
Exemplo n.º 33
0
    def attach_metadata(self, objects, request=None):
        from sentry.templatetags.sentry_plugins import handle_before_events

        attach_foreignkey(objects, Group.project, ['team'])

        GroupMeta.objects.populate_cache(objects)

        if request and objects:
            handle_before_events(request, objects)

        if request and request.user.is_authenticated() and objects:
            bookmarks = set(GroupBookmark.objects.filter(
                user=request.user,
                group__in=objects,
            ).values_list('group_id', flat=True))
            seen_groups = dict(GroupSeen.objects.filter(
                user=request.user,
                group__in=objects,
            ).values_list('group_id', 'last_seen'))
        else:
            bookmarks = set()
            seen_groups = {}

        if objects:
            end = timezone.now()
            start = end - timedelta(days=1)

            historical_data = tsdb.get_range(
                model=tsdb.models.group,
                keys=[g.id for g in objects],
                start=start,
                end=end,
            )
        else:
            historical_data = {}

        project_list = set(o.project for o in objects)
        tag_keys = set(['sentry:user'])
        project_annotations = {}
        for project in project_list:
            enabled_annotations = ProjectOption.objects.get_value(
                project, 'annotations', ['sentry:user'])
            project_annotations[project] = enabled_annotations
            tag_keys.update(enabled_annotations)

        annotation_counts = defaultdict(dict)
        annotation_results = GroupTagKey.objects.filter(
            group__in=objects,
            key__in=tag_keys,
        ).values_list('key', 'group', 'values_seen')
        for key, group_id, values_seen in annotation_results:
            annotation_counts[key][group_id] = values_seen

        for g in objects:
            g.is_bookmarked = g.pk in bookmarks
            g.historical_data = [x[1] for x in historical_data.get(g.id, [])]
            active_date = g.active_at or g.first_seen
            g.has_seen = seen_groups.get(g.id, active_date) > active_date
            g.annotations = []
            for key in sorted(tag_keys):
                if key in project_annotations[project]:
                    label = TAG_LABELS.get(key, key.replace('_', ' ')).lower() + 's'
                    try:
                        value = annotation_counts[key].get(g.id, 0)
                    except KeyError:
                        value = 0
                    g.annotations.append({
                        'label': label,
                        'count': value,
                    })
Exemplo n.º 34
0
    def get_attrs(self, item_list, user):
        project_ids = [i.id for i in item_list]
        if user.is_authenticated() and item_list:
            bookmarks = set(
                ProjectBookmark.objects.filter(
                    user=user,
                    project_id__in=project_ids,
                ).values_list('project_id', flat=True)
            )
            user_options = {
                (u.project_id, u.key): u.value
                for u in UserOption.objects.filter(
                    Q(user=user, project__in=item_list, key='mail:alert') |
                    Q(user=user, key='subscribe_by_default', project__isnull=True)
                )
            }
            default_subscribe = (user_options.get(
                'subscribe_by_default', '1') == '1')
        else:
            bookmarks = set()
            user_options = {}
            default_subscribe = False

        if self.stats_period:
            # we need to compute stats at 1d (1h resolution), and 14d
            project_ids = [o.id for o in item_list]

            segments, interval = STATS_PERIOD_CHOICES[self.stats_period]
            now = timezone.now()
            stats = tsdb.get_range(
                model=tsdb.models.project,
                keys=project_ids,
                end=now,
                start=now - ((segments - 1) * interval),
                rollup=int(interval.total_seconds()),
                environment_id=self.environment_id,
            )
        else:
            stats = None

        avatars = {a.project_id: a for a in ProjectAvatar.objects.filter(project__in=item_list)}
        project_ids = [i.id for i in item_list]
        platforms = ProjectPlatform.objects.filter(
            project_id__in=project_ids,
        ).values_list('project_id', 'platform')
        platforms_by_project = defaultdict(list)
        for project_id, platform in platforms:
            platforms_by_project[project_id].append(platform)

        result = self.get_access_by_project(item_list, user)
        for item in item_list:
            result[item].update({
                'is_bookmarked': item.id in bookmarks,
                'is_subscribed':
                bool(user_options.get(
                    (item.id, 'mail:alert'),
                    default_subscribe,
                )),
                'avatar': avatars.get(item.id),
                'platforms': platforms_by_project[item.id]
            })
            if stats:
                result[item]['stats'] = stats[item.id]
        return result
Exemplo n.º 35
0
    def get(self, request, organization):
        """
        Retrieve Event Counts for an Organization
        `````````````````````````````````````````

        .. caution::
           This endpoint may change in the future without notice.

        Return a set of points representing a normalized timestamp and the
        number of events seen in the period.

        :pparam string organization_slug: the slug of the organization for
                                          which the stats should be
                                          retrieved.
        :qparam string stat: the name of the stat to query (``"received"``,
                             ``"rejected"``, ``"blacklisted"``)
        :qparam timestamp since: a timestamp to set the start of the query
                                 in seconds since UNIX epoch.
        :qparam timestamp until: a timestamp to set the end of the query
                                 in seconds since UNIX epoch.
        :qparam string resolution: an explicit resolution to search
                                   for (eg: ``10s``).  This should not be
                                   used unless you are familiar with Sentry's
                                   internals as it's restricted to pre-defined
                                   values.
        :auth: required
        """
        group = request.GET.get('group', 'organization')
        if group == 'organization':
            keys = [organization.id]
        elif group == 'project':
            team_list = Team.objects.get_for_user(
                organization=organization,
                user=request.user,
            )

            project_list = []
            for team in team_list:
                project_list.extend(
                    Project.objects.get_for_user(
                        team=team,
                        user=request.user,
                    ))
            keys = list({p.id for p in project_list})
        else:
            raise ValueError('Invalid group: %s' % group)

        if 'id' in request.GET:
            id_filter_set = frozenset(map(int, request.GET.getlist('id')))
            keys = [k for k in keys if k in id_filter_set]

        if not keys:
            return Response([])

        stat_model = None
        stat = request.GET.get('stat', 'received')
        query_kwargs = {}
        if stat == 'received':
            if group == 'project':
                stat_model = tsdb.models.project_total_received
            else:
                stat_model = tsdb.models.organization_total_received
        elif stat == 'rejected':
            if group == 'project':
                stat_model = tsdb.models.project_total_rejected
            else:
                stat_model = tsdb.models.organization_total_rejected
        elif stat == 'blacklisted':
            if group == 'project':
                stat_model = tsdb.models.project_total_blacklisted
            else:
                stat_model = tsdb.models.organization_total_blacklisted
        elif stat == 'generated':
            if group == 'project':
                stat_model = tsdb.models.project
                try:
                    query_kwargs[
                        'environment_id'] = self._get_environment_id_from_request(
                            request,
                            organization.id,
                        )
                except Environment.DoesNotExist:
                    raise ResourceDoesNotExist

        if stat_model is None:
            raise ValueError('Invalid group: %s, stat: %s' % (group, stat))

        data = tsdb.get_range(model=stat_model,
                              keys=keys,
                              **self._parse_args(request, **query_kwargs))

        if group == 'organization':
            data = data[organization.id]

        return Response(data)
Exemplo n.º 36
0
    def get(self, request, group):
        """
        Retrieve an Issue
        `````````````````

        Return details on an individual issue. This returns the basic stats for
        the issue (title, last seen, first seen), some overall numbers (number
        of comments, user reports) as well as the summarized event data.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """
        # TODO(dcramer): handle unauthenticated/public response
        data = serialize(group, request.user)

        # TODO: these probably should be another endpoint
        activity = self._get_activity(request, group, num=100)
        seen_by = self._get_seen_by(request, group)

        first_release = group.get_first_release()

        if first_release is not None:
            last_release = group.get_last_release()
        else:
            last_release = None

        action_list = self._get_actions(request, group)

        now = timezone.now()
        hourly_stats = tsdb.rollup(
            tsdb.get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=1),
            ), 3600
        )[group.id]
        daily_stats = tsdb.rollup(
            tsdb.get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=30),
            ), 3600 * 24
        )[group.id]

        if first_release:
            first_release = self._get_release_info(request, group, first_release)
        if last_release:
            last_release = self._get_release_info(request, group, last_release)

        tags = tagstore.get_group_tag_keys(group.id, limit=100)

        participants = list(
            User.objects.filter(
                groupsubscription__is_active=True,
                groupsubscription__group=group,
            )
        )

        data.update(
            {
                'firstRelease': first_release,
                'lastRelease': last_release,
                'activity': serialize(activity, request.user),
                'seenBy': seen_by,
                'participants': serialize(participants, request.user),
                'pluginActions': action_list,
                'pluginIssues': self._get_available_issue_plugins(request, group),
                'pluginContexts': self._get_context_plugins(request, group),
                'userReportCount': UserReport.objects.filter(group=group).count(),
                'tags': sorted(serialize(tags, request.user), key=lambda x: x['name']),
                'stats': {
                    '24h': hourly_stats,
                    '30d': daily_stats,
                }
            }
        )

        return Response(data)
Exemplo n.º 37
0
    def get(self, request, organization):
        """
        Retrieve Event Counts for an Organization
        `````````````````````````````````````````

        .. caution::
           This endpoint may change in the future without notice.

        Return a set of points representing a normalized timestamp and the
        number of events seen in the period.

        :pparam string organization_slug: the slug of the organization for
                                          which the stats should be
                                          retrieved.
        :qparam string stat: the name of the stat to query (``"received"``,
                             ``"rejected"``, ``"blacklisted"``)
        :qparam timestamp since: a timestamp to set the start of the query
                                 in seconds since UNIX epoch.
        :qparam timestamp until: a timestamp to set the end of the query
                                 in seconds since UNIX epoch.
        :qparam string resolution: an explicit resolution to search
                                   for (eg: ``10s``).  This should not be
                                   used unless you are familiar with Sentry's
                                   internals as it's restricted to pre-defined
                                   values.
        :auth: required
        """
        group = request.GET.get('group', 'organization')
        if group == 'organization':
            keys = [organization.id]
        elif group == 'project':
            team_list = Team.objects.get_for_user(
                organization=organization,
                user=request.user,
            )

            project_list = []
            for team in team_list:
                project_list.extend(Project.objects.get_for_user(
                    team=team,
                    user=request.user,
                ))
            keys = [p.id for p in project_list]
        else:
            raise ValueError('Invalid group: %s' % group)

        if 'id' in request.GET:
            id_filter_set = frozenset(map(int, request.GET.getlist('id')))
            keys = [k for k in keys if k in id_filter_set]

        if not keys:
            return Response([])

        stat_model = None
        stat = request.GET.get('stat', 'received')
        query_kwargs = {}
        if stat == 'received':
            if group == 'project':
                stat_model = tsdb.models.project_total_received
            else:
                stat_model = tsdb.models.organization_total_received
        elif stat == 'rejected':
            if group == 'project':
                stat_model = tsdb.models.project_total_rejected
            else:
                stat_model = tsdb.models.organization_total_rejected
        elif stat == 'blacklisted':
            if group == 'project':
                stat_model = tsdb.models.project_total_blacklisted
            else:
                stat_model = tsdb.models.organization_total_blacklisted
        elif stat == 'generated':
            if group == 'project':
                stat_model = tsdb.models.project
                try:
                    query_kwargs['environment_id'] = self._get_environment_id_from_request(
                        request,
                        organization.id,
                    )
                except Environment.DoesNotExist:
                    raise ResourceDoesNotExist

        if stat_model is None:
            raise ValueError('Invalid group: %s, stat: %s' % (group, stat))

        data = tsdb.get_range(model=stat_model, keys=keys,
                              **self._parse_args(request, **query_kwargs))

        if group == 'organization':
            data = data[organization.id]

        return Response(data)
Exemplo n.º 38
0
    def get_attrs(self, item_list, user):
        def measure_span(op_tag):
            span = sentry_sdk.start_span(
                op="serialize.get_attrs.project.{}".format(op_tag))
            span.set_data("Object Count", len(item_list))
            return span

        with measure_span("preamble"):
            project_ids = [i.id for i in item_list]
            if user.is_authenticated() and item_list:
                bookmarks = set(
                    ProjectBookmark.objects.filter(
                        user=user,
                        project_id__in=project_ids).values_list("project_id",
                                                                flat=True))
                user_options = {
                    (u.project_id, u.key): u.value
                    for u in UserOption.objects.filter(
                        Q(user=user, project__in=item_list, key="mail:alert")
                        | Q(user=user,
                            key="subscribe_by_default",
                            project__isnull=True))
                }
                default_subscribe = user_options.get("subscribe_by_default",
                                                     "1") == "1"
            else:
                bookmarks = set()
                user_options = {}
                default_subscribe = False

            if self.stats_period:
                # we need to compute stats at 1d (1h resolution), and 14d
                project_ids = [o.id for o in item_list]

                segments, interval = STATS_PERIOD_CHOICES[self.stats_period]
                now = timezone.now()
                stats = tsdb.get_range(
                    model=tsdb.models.project,
                    keys=project_ids,
                    end=now,
                    start=now - ((segments - 1) * interval),
                    rollup=int(interval.total_seconds()),
                    environment_ids=self.environment_id
                    and [self.environment_id],
                )
            else:
                stats = None

            avatars = {
                a.project_id: a
                for a in ProjectAvatar.objects.filter(project__in=item_list)
            }
            project_ids = [i.id for i in item_list]
            platforms = ProjectPlatform.objects.filter(
                project_id__in=project_ids).values_list(
                    "project_id", "platform")
            platforms_by_project = defaultdict(list)
            for project_id, platform in platforms:
                platforms_by_project[project_id].append(platform)

        with measure_span("access"):
            result = self.get_access_by_project(item_list, user)

        with measure_span("features"):
            features_by_project = self._get_features_for_projects(
                item_list, user)
            for project, serialized in result.items():
                serialized["features"] = features_by_project[project]

        with measure_span("other"):
            for project, serialized in result.items():
                serialized.update({
                    "is_bookmarked":
                    project.id in bookmarks,
                    "is_subscribed":
                    bool(
                        user_options.get((project.id, "mail:alert"),
                                         default_subscribe)),
                    "avatar":
                    avatars.get(project.id),
                    "platforms":
                    platforms_by_project[project.id],
                })
                if stats:
                    serialized["stats"] = stats[project.id]
        return result