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
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()
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()
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()
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: