Example #1
0
def needed_elements_of_expression(expression):
    if expression[0] in ["rrd", "scalar"]:
        yield tuple(expression[1:])
    elif expression[0] in ["operator", "transformation"]:
        for operand in expression[2]:
            yield from needed_elements_of_expression(operand)
    elif expression[0] == "combined" and not cmk_version.is_raw_edition():
        # Suppression is needed to silence pylint in CRE environment
        from cmk.gui.cee.plugins.metrics.graphs import (  # pylint: disable=no-name-in-module # isort: skip
            resolve_combined_single_metric_spec,)
        metrics = resolve_combined_single_metric_spec(expression[1])

        for out in (needed_elements_of_expression(m['expression']) for m in metrics):
            yield from out
Example #2
0
def evaluate_time_series_expression(expression, rrd_data) -> List[TimeSeries]:
    if rrd_data:
        sample_data = next(iter(rrd_data.values()))
        num_points = len(sample_data)
        twindow = sample_data.twindow
    else:
        # no data, default clean graph, use for pure scalars on custom graphs
        num_points = 1
        twindow = (0, 60, 60)

    if expression[0] == "operator":
        operator_id, operands = expression[1:]
        operands_evaluated_l = [evaluate_time_series_expression(a, rrd_data) for a in operands]
        operands_evaluated = [item for lists in operands_evaluated_l for item in lists]
        return [time_series_math(operator_id, operands_evaluated)]

    if expression[0] == "transformation":
        (transform, conf), operands = expression[1:]
        operands_evaluated = evaluate_time_series_expression(operands[0], rrd_data)
        return evaluate_timeseries_transformation(transform, conf, operands_evaluated)

    if expression[0] == "rrd":
        key = tuple(expression[1:])
        if key in rrd_data:
            return [rrd_data[key]]
        return [TimeSeries([None] * num_points, twindow)]

    if expression[0] == "constant":
        return [TimeSeries([expression[1]] * num_points, twindow)]

    if expression[0] == "combined":
        metrics = resolve_combined_single_metric_spec(expression[1])
        curves = []
        for m in metrics:
            for curve in evaluate_time_series_expression(m['expression'], rrd_data):
                curve.metadata = {k: m[k] for k in m if k in ['line_type', 'title']}
                curves.append(curve)

        return curves

    raise NotImplementedError()
Example #3
0
def evaluate_time_series_expression(expression, rrd_data):
    if rrd_data:
        sample_data = next(iter(rrd_data.values()))
        num_points = len(sample_data)
        twindow = sample_data.twindow
    else:
        # no data, default clean graph, use for pure scalars on custom graphs
        num_points = 1
        twindow = (0, 60, 60)

    if expression[0] == "operator":
        operator_id, operands = expression[1:]
        operands_evaluated = [evaluate_time_series_expression(a, rrd_data) for a in operands]
        return time_series_math(operator_id, operands_evaluated)

    if expression[0] == "transformation":
        (transform, conf), operands = expression[1:]
        operands_evaluated = evaluate_time_series_expression(operands[0], rrd_data)
        return evaluate_timeseries_transformation(transform, conf, operands_evaluated)

    if expression[0] == "rrd":
        key = tuple(expression[1:])
        if key in rrd_data:
            return rrd_data[key]
        return TimeSeries([None] * num_points, twindow)

    if expression[0] == "constant":
        return TimeSeries([expression[1]] * num_points, twindow)

    if expression[0] == "combined":
        metrics = resolve_combined_single_metric_spec(expression[1])

        return [(m["line_type"], m["color"], m['title'],
                 evaluate_time_series_expression(m['expression'], rrd_data)) for m in metrics]

    raise NotImplementedError()
Example #4
0
def evaluate_time_series_expression(expression, rrd_data):
    if rrd_data:
        num_points = len(next(iter(rrd_data.values())))
    else:
        num_points = 1

    if expression[0] == "operator":
        operator_id, operands = expression[1:]
        operands_evaluated = [
            evaluate_time_series_expression(a, rrd_data) for a in operands
        ]
        return time_series_math(operator_id, operands_evaluated)

    if expression[0] == "transformation":
        (transform, conf), operands = expression[1:]
        operands_evaluated = evaluate_time_series_expression(
            operands[0], rrd_data)
        if transform == 'percentile':
            return time_series_operator_perc(operands_evaluated, conf)

        if transform == 'filter_top':
            if isinstance(operands_evaluated, TimeSeries):
                return operands_evaluated
            return operands_evaluated[:conf["amount"]]

        if transform == 'value_sort':
            if isinstance(operands_evaluated, TimeSeries):
                return operands_evaluated

            aggr_func = {
                "min": lambda x: min(x or [0]),
                "max": lambda x: max(x or [0]),
                "average": lambda x: sum(x) / float(len(x) or 1),
            }[conf['aggregation']]

            orderlist = sorted(operands_evaluated,
                               key=lambda metric: aggr_func(
                                   clean_time_series_point(metric[3])),
                               reverse=conf["reverse"])

            # fix multi-line stack line styling
            if orderlist[0][0] == 'stack':
                line_types = ['area'] + ['stack'] * (len(orderlist) - 1)
                orderlist = [(lt, ) + metric[1:]
                             for lt, metric in zip(line_types, orderlist)]

            return orderlist

        if transform == 'forecast':
            if cmk_version.is_raw_edition():
                raise MKGeneralException(
                    _("Forecast calculations are only available with the "
                      "Checkmk Enterprise Editions"))
            # Suppression is needed to silence pylint in CRE environment
            from cmk.gui.cee.plugins.metrics.forecasts import time_series_transform_forecast  # pylint: disable=no-name-in-module
            return time_series_transform_forecast(
                TimeSeries(operands_evaluated, rrd_data['__range']), conf)

    if expression[0] == "rrd":
        key = tuple(expression[1:])
        if key in rrd_data:
            return rrd_data[key]
        return [None] * num_points

    if expression[0] == "constant":
        return [expression[1]] * num_points

    if expression[0] == "combined" and not cmk_version.is_raw_edition():
        # Suppression is needed to silence pylint in CRE environment
        from cmk.gui.cee.plugins.metrics.graphs import resolve_combined_single_metric_spec  # pylint: disable=no-name-in-module
        metrics = resolve_combined_single_metric_spec(expression[1])

        return [(m["line_type"], m["color"], m['title'],
                 evaluate_time_series_expression(m['expression'], rrd_data))
                for m in metrics]

    raise NotImplementedError()
Example #5
0
    if expression[0] == "transformation":
        (transform, conf), operands = expression[1:]
        operands_evaluated = evaluate_time_series_expression(operands[0], rrd_data)
        return evaluate_timeseries_transformation(transform, conf, operands_evaluated)

    if expression[0] == "rrd":
        key = tuple(expression[1:])
        if key in rrd_data:
            return [rrd_data[key]]
        return [TimeSeries([None] * num_points, twindow)]

    if expression[0] == "constant":
        return [TimeSeries([expression[1]] * num_points, twindow)]

    if expression[0] == "combined":
        metrics = resolve_combined_single_metric_spec(expression[1])
        curves = []
        for m in metrics:
            for curve in evaluate_time_series_expression(m['expression'], rrd_data):
                curve.metadata = {k: m[k] for k in m if k in ['line_type', 'title']}
                curves.append(curve)

        return curves

    raise NotImplementedError()


def time_series_math(operator_id: Literal["+", "*", "-", "/", "MAX", "MIN", "AVERAGE", "MERGE"],
                     operands_evaluated: List[TimeSeries]) -> Optional[TimeSeries]:
    operators = time_series_operators()
    if operator_id not in operators: