예제 #1
0
파일: logic.py 프로젝트: yujiaqi/sentry
def get_incident_event_stats(incident, start=None, end=None, windowed_stats=False):
    """
    Gets event stats for an incident. If start/end are provided, uses that time
    period, otherwise uses the incident start/current_end.
    """
    query_params = build_incident_query_params(
        incident, start=start, end=end, windowed_stats=windowed_stats
    )
    time_window = incident.alert_rule.snuba_query.time_window
    aggregations = query_params.pop("aggregations")[0]
    snuba_params = [
        SnubaQueryParams(
            aggregations=[(aggregations[0], aggregations[1], "count")],
            orderby="time",
            groupby=["time"],
            rollup=time_window,
            limit=10000,
            **query_params
        )
    ]

    # We want to include the specific buckets for the incident start and closed times,
    # so that there's no need to interpolate to show them on the frontend. If they're
    # cleanly divisible by the `time_window` then there's no need to fetch, since
    # they'll be included in the standard results anyway.
    extra_buckets = []
    if int(to_timestamp(incident.date_started)) % time_window:
        extra_buckets.append(incident.date_started)
    if incident.date_closed and int(to_timestamp(incident.date_closed)) % time_window:
        extra_buckets.append(incident.date_closed.replace(second=0, microsecond=0))

    # We make extra queries to fetch these buckets
    for bucket_start in extra_buckets:
        extra_bucket_query_params = build_incident_query_params(
            incident, start=bucket_start, end=bucket_start + timedelta(seconds=time_window)
        )
        aggregations = extra_bucket_query_params.pop("aggregations")[0]
        snuba_params.append(
            SnubaQueryParams(
                aggregations=[(aggregations[0], aggregations[1], "count")],
                limit=1,
                **extra_bucket_query_params
            )
        )

    results = bulk_raw_query(snuba_params, referrer="incidents.get_incident_event_stats")
    # Once we receive the results, if we requested extra buckets we now need to label
    # them with timestamp data, since the query we ran only returns the count.
    for extra_start, result in zip(extra_buckets, results[1:]):
        result["data"][0]["time"] = int(to_timestamp(extra_start))
    merged_data = list(chain(*[r["data"] for r in results]))
    merged_data.sort(key=lambda row: row["time"])
    results[0]["data"] = merged_data

    return SnubaTSResult(
        results[0], snuba_params[0].start, snuba_params[0].end, snuba_params[0].rollup
    )
예제 #2
0
파일: logic.py 프로젝트: sinanargun/sentry
def bulk_get_incident_event_stats(incidents,
                                  query_params_list,
                                  data_points=50):
    snuba_params_list = [
        SnubaQueryParams(
            aggregations=[(
                query_aggregation_to_snuba[QueryAggregations(
                    incident.aggregation)][0],
                query_aggregation_to_snuba[QueryAggregations(
                    incident.aggregation)][1],
                "count",
            )],
            orderby="time",
            groupby=["time"],
            rollup=max(int(incident.duration.total_seconds() / data_points),
                       1),
            limit=10000,
            **query_param)
        for incident, query_param in zip(incidents, query_params_list)
    ]
    results = bulk_raw_query(snuba_params_list,
                             referrer="incidents.get_incident_event_stats")
    return [
        SnubaTSResult(result, snuba_params.start, snuba_params.end,
                      snuba_params.rollup)
        for snuba_params, result in zip(snuba_params_list, results)
    ]
예제 #3
0
    def test_transactions_dataset_with_project_id(self):
        query_params = SnubaQueryParams(
            dataset=Dataset.Transactions,
            filter_keys={"project_id": [self.project.id]})

        kwargs, _, _ = _prepare_query_params(query_params)
        assert kwargs["project"] == [self.project.id]
예제 #4
0
    def test_outcomes_dataset_with_org_id(self):
        query_params = SnubaQueryParams(
            dataset=Dataset.Outcomes,
            filter_keys={"org_id": [self.organization.id]})

        kwargs, _, _ = _prepare_query_params(query_params)
        assert kwargs["organization"] == self.organization.id
예제 #5
0
파일: logic.py 프로젝트: wenlaizhou/sentry
def get_incident_aggregates(incident,
                            start=None,
                            end=None,
                            windowed_stats=False,
                            use_alert_aggregate=False):
    """
    Calculates aggregate stats across the life of an incident, or the provided range.
    If `use_alert_aggregate` is True, calculates just the aggregate that the alert is
    for, and returns as the `count` key.
    If False, returns two values:
    - count: Total count of events
    - unique_users: Total number of unique users
    """
    query_params = build_incident_query_params(incident, start, end,
                                               windowed_stats)
    if not use_alert_aggregate:
        query_params["aggregations"] = [
            ("count()", "", "count"),
            ("uniq", "tags[sentry:user]", "unique_users"),
        ]
    else:
        query_params["aggregations"][0][2] = "count"
    snuba_params_list = [SnubaQueryParams(limit=10000, **query_params)]
    results = bulk_raw_query(snuba_params_list,
                             referrer="incidents.get_incident_aggregates")
    return results[0]["data"][0]
예제 #6
0
def bulk_get_incident_event_stats(incidents, query_params_list):
    snuba_params_list = [
        SnubaQueryParams(
            aggregations=[(
                query_aggregation_to_snuba[QueryAggregations(
                    incident.aggregation)][0],
                query_aggregation_to_snuba[QueryAggregations(
                    incident.aggregation)][1],
                "count",
            )],
            orderby="time",
            groupby=["time"],
            rollup=incident.alert_rule.time_window *
            60 if incident.alert_rule is not None else 1 *
            60,  # TODO: When time_window is persisted, switch to using that instead of alert_rule.time_window.
            limit=10000,
            **query_param)
        for incident, query_param in zip(incidents, query_params_list)
    ]
    results = bulk_raw_query(snuba_params_list,
                             referrer="incidents.get_incident_event_stats")
    return [
        SnubaTSResult(result, snuba_params.start, snuba_params.end,
                      snuba_params.rollup)
        for snuba_params, result in zip(snuba_params_list, results)
    ]
예제 #7
0
파일: logic.py 프로젝트: vivekanon/sentry
def bulk_get_incident_event_stats(incidents,
                                  query_params_list,
                                  data_points=50):
    snuba_params_list = [
        SnubaQueryParams(
            aggregations=[
                ('count()', '', 'count'),
            ],
            orderby='time',
            groupby=['time'],
            rollup=max(int(incident.duration.total_seconds() / data_points),
                       1),
            limit=10000,
            **query_param)
        for incident, query_param in zip(incidents, query_params_list)
    ]
    results = bulk_raw_query(snuba_params_list,
                             referrer='incidents.get_incident_event_stats')
    return [
        SnubaTSResult(
            result,
            snuba_params.start,
            snuba_params.end,
            snuba_params.rollup,
        ) for snuba_params, result in zip(snuba_params_list, results)
    ]
예제 #8
0
    def test_outcomes_dataset_with_key_id(self):
        key = self.create_project_key(project=self.project)
        query_params = SnubaQueryParams(dataset=Dataset.Outcomes,
                                        filter_keys={"key_id": [key.id]})

        kwargs, _, _ = _prepare_query_params(query_params)
        assert kwargs["organization"] == self.organization.id
예제 #9
0
파일: logic.py 프로젝트: FengLee1113/sentry
def get_incident_event_stats(incident,
                             start=None,
                             end=None,
                             windowed_stats=False):
    """
    Gets event stats for an incident. If start/end are provided, uses that time
    period, otherwise uses the incident start/current_end.
    """
    query_params = build_incident_query_params(incident,
                                               start=start,
                                               end=end,
                                               windowed_stats=windowed_stats)
    snuba_params = SnubaQueryParams(
        aggregations=[(
            query_aggregation_to_snuba[aggregate_to_query_aggregation[
                incident.alert_rule.snuba_query.aggregate]][0],
            query_aggregation_to_snuba[aggregate_to_query_aggregation[
                incident.alert_rule.snuba_query.aggregate]][1],
            "count",
        )],
        orderby="time",
        groupby=["time"],
        rollup=incident.alert_rule.snuba_query.time_window,
        limit=10000,
        **query_params)

    results = bulk_raw_query([snuba_params],
                             referrer="incidents.get_incident_event_stats")
    return SnubaTSResult(results[0], snuba_params.start, snuba_params.end,
                         snuba_params.rollup)
예제 #10
0
    def test_with_deleted_project(self):
        query_params = SnubaQueryParams(
            dataset=Dataset.Events,
            filter_keys={"project_id": [self.project.id]})

        self.project.delete()
        with pytest.raises(UnqualifiedQueryError):
            get_query_params_to_update_for_projects(query_params)
예제 #11
0
    def test_with_some_deleted_projects(self, mock_project):
        other_project = self.create_project(organization=self.organization, slug="a" * 32)
        query_params = SnubaQueryParams(
            dataset=Dataset.Events, filter_keys={"project_id": [self.project.id, other_project.id]}
        )

        other_project.delete()
        organization_id, _ = get_query_params_to_update_for_projects(query_params)
        assert organization_id == self.organization.id
예제 #12
0
파일: logic.py 프로젝트: wenlaizhou/sentry
 def build_extra_query_params(bucket_start):
     extra_bucket_query_params = build_incident_query_params(
         incident,
         start=bucket_start,
         end=bucket_start + timedelta(seconds=time_window))
     aggregations = extra_bucket_query_params.pop("aggregations")[0]
     return SnubaQueryParams(aggregations=[(aggregations[0],
                                            aggregations[1], "count")],
                             limit=1,
                             **extra_bucket_query_params)
예제 #13
0
def bulk_get_incident_aggregates(query_params_list):
    snuba_params_list = [
        SnubaQueryParams(aggregations=[("count()", "", "count"),
                                       ("uniq", "tags[sentry:user]",
                                        "unique_users")],
                         limit=10000,
                         **query_param) for query_param in query_params_list
    ]
    results = bulk_raw_query(snuba_params_list,
                             referrer="incidents.get_incident_aggregates")
    return [result["data"][0] for result in results]
예제 #14
0
파일: logic.py 프로젝트: vivekanon/sentry
def bulk_get_incident_aggregates(query_params_list):
    snuba_params_list = [
        SnubaQueryParams(aggregations=[
            ('count()', '', 'count'),
            ('uniq', 'tags[sentry:user]', 'unique_users'),
        ],
                         limit=10000,
                         **query_param) for query_param in query_params_list
    ]
    results = bulk_raw_query(snuba_params_list,
                             referrer='incidents.get_incident_aggregates')
    return [result['data'][0] for result in results]
예제 #15
0
 def test_original_query_params_does_not_get_mutated(self):
     snuba_params = SnubaQueryParams(
         dataset=Dataset.Sessions,
         start=datetime.now() - timedelta(hours=1),
         end=datetime.now(),
         groupby=[],
         conditions=[[["environment", "IN", {"development", "abc"}]]],
         filter_keys={"release": [self.create_release(version="1.0.0").id]},
         aggregations=[],
         rollup=86400,
         is_grouprelease=False,
         **{"selected_columns": ["sessions"]},
     )
     conditions = [[["environment", "IN", {"development", "abc"}]]]
     kwargs = {"selected_columns": ["sessions"]}
     _prepare_query_params(snuba_params)
     assert conditions == snuba_params.conditions
     assert kwargs == snuba_params.kwargs
예제 #16
0
def get_incident_aggregates(incident, start=None, end=None, windowed_stats=False):
    """
    Calculates aggregate stats across the life of an incident, or the provided range.
    - count: Total count of events
    - unique_users: Total number of unique users
    """
    query_params = build_incident_query_params(incident, start, end, windowed_stats)
    # We don't care about the specific aggregations here, we just want total event and
    # unique user counts
    query_params.pop("aggregations", None)
    snuba_params_list = [
        SnubaQueryParams(
            aggregations=[("count()", "", "count"), ("uniq", "tags[sentry:user]", "unique_users")],
            limit=10000,
            **query_params
        )
    ]
    results = bulk_raw_query(snuba_params_list, referrer="incidents.get_incident_aggregates")
    return [result["data"][0] for result in results][0]
예제 #17
0
def bulk_get_incident_event_stats(incidents, query_params_list):
    snuba_params_list = [
        SnubaQueryParams(aggregations=[(
            query_aggregation_to_snuba[aggregate_to_query_aggregation[
                incident.alert_rule.snuba_query.aggregate]][0],
            query_aggregation_to_snuba[aggregate_to_query_aggregation[
                incident.alert_rule.snuba_query.aggregate]][1],
            "count",
        )],
                         orderby="time",
                         groupby=["time"],
                         rollup=incident.alert_rule.snuba_query.time_window,
                         limit=10000,
                         **query_param)
        for incident, query_param in zip(incidents, query_params_list)
    ]
    results = bulk_raw_query(snuba_params_list,
                             referrer="incidents.get_incident_event_stats")
    return [
        SnubaTSResult(result, snuba_params.start, snuba_params.end,
                      snuba_params.rollup)
        for snuba_params, result in zip(snuba_params_list, results)
    ]
예제 #18
0
    def test_invalid_dataset_provided(self):
        query_params = SnubaQueryParams(dataset="invalid_dataset")

        with pytest.raises(UnqualifiedQueryError):
            _prepare_query_params(query_params)
예제 #19
0
    def test_outcomes_dataset_with_no_org_id_given(self):
        query_params = SnubaQueryParams(dataset=Dataset.Outcomes)

        with pytest.raises(UnqualifiedQueryError):
            _prepare_query_params(query_params)
예제 #20
0
def query_trace_data(
    trace_id: str, params: Mapping[str, str]
) -> Tuple[Sequence[SnubaTransaction], Sequence[SnubaError]]:
    transaction_query = discover.prepare_discover_query(
        selected_columns=[
            "id",
            "transaction.status",
            "transaction.op",
            "transaction.duration",
            "transaction",
            "timestamp",
            # project gets the slug, and project.id gets added automatically
            "project",
            "trace.span",
            "trace.parent_span",
            'to_other(trace.parent_span, "", 0, 1) AS root',
        ],
        # We want to guarantee at least getting the root, and hopefully events near it with timestamp
        # id is just for consistent results
        orderby=["-root", "timestamp", "id"],
        params=params,
        query=f"event.type:transaction trace:{trace_id}",
    )
    error_query = discover.prepare_discover_query(
        selected_columns=[
            "id",
            "project",
            "timestamp",
            "trace.span",
            "transaction",
            "issue",
            "title",
            "tags[level]",
        ],
        # Don't add timestamp to this orderby as snuba will have to split the time range up and make multiple queries
        orderby=["id"],
        params=params,
        query=f"!event.type:transaction trace:{trace_id}",
        auto_fields=False,
    )
    snuba_params = [
        SnubaQueryParams(
            dataset=Dataset.Discover,
            start=snuba_filter.start,
            end=snuba_filter.end,
            groupby=snuba_filter.groupby,
            conditions=snuba_filter.conditions,
            filter_keys=snuba_filter.filter_keys,
            aggregations=snuba_filter.aggregations,
            selected_columns=snuba_filter.selected_columns,
            having=snuba_filter.having,
            orderby=snuba_filter.orderby,
            limit=MAX_TRACE_SIZE,
        )
        for snuba_filter in [transaction_query.filter, error_query.filter]
    ]
    results = bulk_raw_query(
        snuba_params,
        referrer="api.trace-view.get-events",
    )
    transformed_results = [
        discover.transform_results(result, query.fields["functions"], query.columns, query.filter)[
            "data"
        ]
        for result, query in zip(results, [transaction_query, error_query])
    ]
    return cast(Sequence[SnubaTransaction], transformed_results[0]), cast(
        Sequence[SnubaError], transformed_results[1]
    )