def get(self, request, organization): project_ids = self.get_requested_project_ids(request) projects = self.get_projects(request, organization, project_ids) len_projects = len(project_ids) sentry_sdk.set_tag("query.num_projects", len_projects) sentry_sdk.set_tag("query.num_projects.grouped", format_grouped_length(len_projects)) if len(projects) == 0: return Response([]) with self.handle_query_errors(): result = discover.query( query="has:sdk.version", selected_columns=[ "project", "sdk.name", "sdk.version", "last_seen()" ], orderby="-project", params={ "start": timezone.now() - timedelta(days=1), "end": timezone.now(), "organization_id": organization.id, "project_id": [p.id for p in projects], }, referrer="api.organization-sdk-updates", ) return Response(serialize(result["data"], projects))
def record_analytics(transactions: Sequence[SnubaTransaction], trace_id: str, user_id: int, org_id: int) -> None: with sentry_sdk.start_span(op="recording.analytics"): len_transactions = len(transactions) sentry_sdk.set_tag("trace_view.trace", trace_id) sentry_sdk.set_tag("trace_view.transactions", len_transactions) sentry_sdk.set_tag("trace_view.transactions.grouped", format_grouped_length(len_transactions)) projects: Set[int] = set() for transaction in transactions: projects.add(transaction["project.id"]) len_projects = len(projects) sentry_sdk.set_tag("trace_view.projects", len_projects) sentry_sdk.set_tag("trace_view.projects.grouped", format_grouped_length(len_projects))
def test_format_grouped_length(): assert format_grouped_length(0) == "0" assert format_grouped_length(1) == "1" assert format_grouped_length(2) == "<10" assert format_grouped_length(10) == "<100" assert format_grouped_length(50) == "<100" assert format_grouped_length(100) == ">100" assert format_grouped_length(25, [50]) == "<50"
def resolve_team_key_transaction_alias( builder: QueryBuilder, resolve_metric_index: bool = False ) -> SelectType: org_id = builder.params.get("organization_id") project_ids = builder.params.get("project_id") team_ids = builder.params.get("team_id") if org_id is None or team_ids is None or project_ids is None: raise TypeError("Team key transactions parameters cannot be None") team_key_transactions = list( TeamKeyTransaction.objects.filter( organization_id=org_id, project_team__in=ProjectTeam.objects.filter( project_id__in=project_ids, team_id__in=team_ids ), ) .order_by("transaction", "project_team__project_id") .values_list("project_team__project_id", "transaction") .distinct("transaction", "project_team__project_id")[ : fields.MAX_QUERYABLE_TEAM_KEY_TRANSACTIONS ] ) count = len(team_key_transactions) if resolve_metric_index: team_key_transactions = [ (project, indexer.resolve(transaction)) for project, transaction in team_key_transactions ] # NOTE: this raw count is not 100% accurate because if it exceeds # `MAX_QUERYABLE_TEAM_KEY_TRANSACTIONS`, it will not be reflected sentry_sdk.set_tag("team_key_txns.count", count) sentry_sdk.set_tag( "team_key_txns.count.grouped", format_grouped_length(count, [10, 100, 250, 500]) ) if count == 0: return Function("toInt8", [0], constants.TEAM_KEY_TRANSACTION_ALIAS) return Function( "in", [ (builder.column("project_id"), builder.column("transaction")), team_key_transactions, ], constants.TEAM_KEY_TRANSACTION_ALIAS, )
def get_filter_params(self, request: Request, organization, date_filter_optional=False, project_ids=None): """ Extracts common filter parameters from the request and returns them in a standard format. :param request: :param organization: Organization to get params for :param date_filter_optional: Defines what happens if no date filter :param project_ids: Project ids if they were already grabbed but not validated yet parameters are passed. If False, no date filtering occurs. If True, we provide default values. :return: A dict with keys: - start: start date of the filter - end: end date of the filter - project_id: A list of project ids to filter on - environment(optional): If environments were passed in, a list of environment names """ # get the top level params -- projects, time range, and environment # from the request try: start, end = get_date_range_from_params( request.GET, optional=date_filter_optional) if start and end: total_seconds = (end - start).total_seconds() sentry_sdk.set_tag("query.period", total_seconds) one_day = 86400 grouped_period = ">30d" if total_seconds <= one_day: grouped_period = "<=1d" elif total_seconds <= one_day * 7: grouped_period = "<=7d" elif total_seconds <= one_day * 14: grouped_period = "<=14d" elif total_seconds <= one_day * 30: grouped_period = "<=30d" sentry_sdk.set_tag("query.period.grouped", grouped_period) except InvalidParams as e: raise ParseError(detail=f"Invalid date range: {e}") try: projects = self.get_projects(request, organization, project_ids) except ValueError: raise ParseError(detail="Invalid project ids") if not projects: raise NoProjects len_projects = len(projects) sentry_sdk.set_tag("query.num_projects", len_projects) sentry_sdk.set_tag("query.num_projects.grouped", format_grouped_length(len_projects)) params = { "start": start, "end": end, "project_id": [p.id for p in projects], "organization_id": organization.id, } environments = self.get_environments(request, organization) if environments: params["environment"] = [env.name for env in environments] params["environment_objects"] = environments return params