def populate_measurements(self, specs):
        start = before_now(minutes=5)
        for spec in specs:
            spec = HistogramSpec(*spec)
            for field, count in spec.fields:
                if not is_measurement(field):
                    continue

                measurement = get_measurement_name(field)
                for i in range(count):
                    data = deepcopy(self.data)

                    data["timestamp"] = iso_format(start)
                    data["start_timestamp"] = iso_format(start - timedelta(seconds=i))
                    value = random.random() * (spec.end - spec.start) + spec.start
                    data["transaction"] = "/measurement/{}/value/{}".format(measurement, value)

                    data["measurements"] = {measurement: {"value": value}}
                    self.store_event(data, self.project.id)
Example #2
0
def histogram_query(
    fields,
    user_query,
    params,
    num_buckets,
    precision=0,
    min_value=None,
    max_value=None,
    data_filter=None,
    referrer=None,
):
    """
    API for generating histograms for numeric columns.

    A multihistogram is possible only if the columns are all measurements.
    The resulting histograms will have their bins aligned.

    :param [str] fields: The list of fields for which you want to generate histograms for.
    :param str user_query: Filter query string to create conditions from.
    :param {str: str} params: Filtering parameters with start, end, project_id, environment
    :param int num_buckets: The number of buckets the histogram should contain.
    :param int precision: The number of decimal places to preserve, default 0.
    :param float min_value: The minimum value allowed to be in the histogram.
        If left unspecified, it is queried using `user_query` and `params`.
    :param float max_value: The maximum value allowed to be in the histogram.
        If left unspecified, it is queried using `user_query` and `params`.
    :param str data_filter: Indicate the filter strategy to be applied to the data.
    """

    multiplier = int(10**precision)
    if max_value is not None:
        # We want the specified max_value to be exclusive, and the queried max_value
        # to be inclusive. So we adjust the specified max_value using the multiplier.
        max_value -= 0.1 / multiplier
    min_value, max_value = find_histogram_min_max(fields, min_value, max_value,
                                                  user_query, params,
                                                  data_filter)

    key_column = None
    conditions = []
    if len(fields) > 1:
        key_column = "array_join(measurements_key)"
        key_alias = get_function_alias(key_column)
        measurements = []
        for f in fields:
            measurement = get_measurement_name(f)
            if measurement is None:
                raise InvalidSearchQuery(
                    u"multihistogram expected all measurements, received: {}".
                    format(f))
            measurements.append(measurement)
        conditions.append([key_alias, "IN", measurements])

    histogram_params = find_histogram_params(num_buckets, min_value, max_value,
                                             multiplier)
    histogram_column = get_histogram_column(fields, key_column,
                                            histogram_params)
    histogram_alias = get_function_alias(histogram_column)

    if min_value is None or max_value is None:
        return normalize_histogram_results(fields, key_column,
                                           histogram_params, {"data": []})
    # make sure to bound the bins to get the desired range of results
    if min_value is not None:
        min_bin = histogram_params.start_offset
        conditions.append([histogram_alias, ">=", min_bin])
    if max_value is not None:
        max_bin = histogram_params.start_offset + histogram_params.bucket_size * num_buckets
        conditions.append([histogram_alias, "<=", max_bin])

    columns = [] if key_column is None else [key_column]
    results = query(
        selected_columns=columns + [histogram_column, "count()"],
        conditions=conditions,
        query=user_query,
        params=params,
        orderby=[histogram_alias],
        limit=len(fields) * num_buckets,
        referrer=referrer,
        auto_fields=True,
        use_aggregate_conditions=True,
        functions_acl=["array_join", "histogram"],
    )

    return normalize_histogram_results(fields, key_column, histogram_params,
                                       results)