def metric_expression_to_graph_recipe_expression( expression: MetricExpression, translated_metrics: TranslatedMetrics, lq_row: Row, enforced_consolidation_function: Optional[GraphConsoldiationFunction], ) -> StackElement: """Convert 'user,util,+,2,*' into this: ('operator', '*', [('operator', '+', [('rrd', 'heute', u'heute', u'CPU utilization', ....""" rrd_base_element = ( "rrd", lq_row["site"], lq_row["host_name"], lq_row.get("service_description", "_HOST_"), ) expression = split_expression(expression)[0] atoms: List[RPNAtom] = [] # Break the RPN into parts and translate each part separately for part, cf in iter_rpn_expression(expression, enforced_consolidation_function): # Some parts are operators. We leave them. We are just interested in # names of metrics. if part in translated_metrics: # name of a variable that we know tme = translated_metrics[part] metric_names = tme.get("orig_name", [part]) # original name before translation # We do the replacement of special characters with _ right here. # Normally it should be a task of the core. But: We have variables # named "/" - which is very silly, but is due to the bogus perf names # of the df check. So the CMC could not really distinguish this from # the RPN operator /. for metric_name, scale in zip(metric_names, tme["scale"]): atoms.append(rrd_base_element + (pnp_cleanup(metric_name), cf, scale)) if len(metric_names) > 1: atoms.append(("operator", "MERGE")) else: try: atoms.append(("constant", float(part))) except ValueError: atoms.append(("operator", part)) return stack_resolver( atoms, is_operator=lambda x: x[0] == "operator", apply_operator=lambda op, a, b: (op + ([a, b], )), apply_element=lambda x: x, )
def test_extract_rpn(text, out): assert utils.split_expression(text) == out