def _solve_rules(self, rules, metrics): """ solve the rules using the given metrics. metrics must contains all needed metrics. :param list[Rule] rules: the :param metrics: :return: :raises: pyparsing.ParseException """ results = {} root_table = SymbolTable('root', ()) for metric_name, values in metrics.items(): # bind to allow "rmq & rmq:xxx" root_table.add_object(Bind(metric_name, Constant(bool(values)))) # bind to allow "rmq:latency" etc root_table.add_subtable( SymbolTable( metric_name, tuple(Bind(k, Constant(v)) for k, v in values.items()))) # build the symbol table for all rules (as boolean) rules_symbols = SymbolTable('rules', ()) root_table.add_subtable(rules_symbols) for rule in rules: rule_name_ = rule['name'] rules_symbols.add_object( Bind( rule_name_, BooleanVariable( partial(get_rule_result, rule_name=rule_name_, rule=rule)))) rules_symbols.add_subtable( SymbolTable(rule_name_, (Bind( 'since', DurationVariable( partial(get_since, rule_name=rule_name_, rule=rule))), ))) parse_manager = EvaluableParseManager(root_table, grammar) for rule in rules: expression_ = rule['expression'] try: results[rule['name']] = parse_manager.parse(expression_)( results) except pyparsing.ParseException as e: logger.debug("error while parsing %r: %s", expression_, e) raise return results