)]}'
{"aodh/evaluator/composite.py":[{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"9f8670be2878b4dda551abbcd4abc4fd0a573ea2","unresolved":false,"context_lines":[{"line_number":12,"context_line":"# under the License."},{"line_number":13,"context_line":"#"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import six"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"from oslo_log import log"},{"line_number":18,"context_line":"from stevedore import NamedExtensionManager"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a68dd71_ee1ece5d","line":15,"updated":"2016-01-25 19:52:21.000000000","message":"3rd party... group with stevedore","commit_id":"a0492f96bc610f3717870058ff5475d62a94fa76"},{"author":{"_account_id":8290,"name":"liusheng","email":"liusheng2048@gmail.com","username":"LiuSheng"},"change_message_id":"b816c0c799f04014b1066460ad4284a5cf3e27ab","unresolved":false,"context_lines":[{"line_number":12,"context_line":"# under the License."},{"line_number":13,"context_line":"#"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import six"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"from oslo_log import log"},{"line_number":18,"context_line":"from stevedore import NamedExtensionManager"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a68dd71_2f05b612","line":15,"in_reply_to":"9a68dd71_ee1ece5d","updated":"2016-01-26 07:02:12.000000000","message":"Done","commit_id":"a0492f96bc610f3717870058ff5475d62a94fa76"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"9f8670be2878b4dda551abbcd4abc4fd0a573ea2","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from stevedore import NamedExtensionManager"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from aodh import evaluator"},{"line_number":21,"context_line":"from aodh.i18n import _"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":24,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"9a68dd71_8e171244","line":21,"updated":"2016-01-25 19:52:21.000000000","message":"never used","commit_id":"a0492f96bc610f3717870058ff5475d62a94fa76"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"8372507b8e29cc7a5811b713abb2bbf970e10b42","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from stevedore import NamedExtensionManager"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from aodh import evaluator"},{"line_number":21,"context_line":"from aodh.i18n import _"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":24,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"9a68dd71_c96bc41c","line":21,"in_reply_to":"9a68dd71_8e171244","updated":"2016-01-25 20:18:16.000000000","message":"nevermind. ignore this.","commit_id":"a0492f96bc610f3717870058ff5475d62a94fa76"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"9f8670be2878b4dda551abbcd4abc4fd0a573ea2","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    __bool__ \u003d _bool_eq_alarm"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    @classmethod"},{"line_number":67,"context_line":"    def change_bool_op(cls, alarm_state):"},{"line_number":68,"context_line":"        if alarm_state \u003d\u003d evaluator.OK:"},{"line_number":69,"context_line":"            cls.__nonzero__ \u003d cls._bool_eq_ok"},{"line_number":70,"context_line":"            cls.__bool__ \u003d cls._bool_eq_ok"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a68dd71_eefc8e73","line":67,"updated":"2016-01-25 19:52:21.000000000","message":"why is this done at class level?","commit_id":"a0492f96bc610f3717870058ff5475d62a94fa76"},{"author":{"_account_id":8290,"name":"liusheng","email":"liusheng2048@gmail.com","username":"LiuSheng"},"change_message_id":"b816c0c799f04014b1066460ad4284a5cf3e27ab","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    __bool__ \u003d _bool_eq_alarm"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    @classmethod"},{"line_number":67,"context_line":"    def change_bool_op(cls, alarm_state):"},{"line_number":68,"context_line":"        if alarm_state \u003d\u003d evaluator.OK:"},{"line_number":69,"context_line":"            cls.__nonzero__ \u003d cls._bool_eq_ok"},{"line_number":70,"context_line":"            cls.__bool__ \u003d cls._bool_eq_ok"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a68dd71_ca588833","line":67,"in_reply_to":"9a68dd71_eefc8e73","updated":"2016-01-26 07:02:12.000000000","message":"that is because it need to change the action of bool() of all sub rules in a composite rule, and used to calculate the result of composite rule expression","commit_id":"a0492f96bc610f3717870058ff5475d62a94fa76"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"9f8670be2878b4dda551abbcd4abc4fd0a573ea2","unresolved":false,"context_lines":[{"line_number":131,"context_line":"            if rule.state \u003d\u003d new_state:"},{"line_number":132,"context_line":"                root_cause_rules.update({name: rule.rule})"},{"line_number":133,"context_line":"        reason_data.update(causative_rules\u003droot_cause_rules)"},{"line_number":134,"context_line":"        description \u003d {evaluator.ALARM: \u0027outside their threshold.\u0027,"},{"line_number":135,"context_line":"                       evaluator.OK: \u0027inside their threshold.\u0027,"},{"line_number":136,"context_line":"                       evaluator.UNKNOWN: \u0027state evaluated to unknown.\u0027}"},{"line_number":137,"context_line":"        params \u003d {\u0027state\u0027: new_state,"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a68dd71_6ef09ec9","line":134,"updated":"2016-01-25 19:52:21.000000000","message":"this seems like a constant we can define once rather than every call.","commit_id":"a0492f96bc610f3717870058ff5475d62a94fa76"},{"author":{"_account_id":8290,"name":"liusheng","email":"liusheng2048@gmail.com","username":"LiuSheng"},"change_message_id":"b816c0c799f04014b1066460ad4284a5cf3e27ab","unresolved":false,"context_lines":[{"line_number":131,"context_line":"            if rule.state \u003d\u003d new_state:"},{"line_number":132,"context_line":"                root_cause_rules.update({name: rule.rule})"},{"line_number":133,"context_line":"        reason_data.update(causative_rules\u003droot_cause_rules)"},{"line_number":134,"context_line":"        description \u003d {evaluator.ALARM: \u0027outside their threshold.\u0027,"},{"line_number":135,"context_line":"                       evaluator.OK: \u0027inside their threshold.\u0027,"},{"line_number":136,"context_line":"                       evaluator.UNKNOWN: \u0027state evaluated to unknown.\u0027}"},{"line_number":137,"context_line":"        params \u003d {\u0027state\u0027: new_state,"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a68dd71_ea4f8c68","line":134,"in_reply_to":"9a68dd71_6ef09ec9","updated":"2016-01-26 07:02:12.000000000","message":"yes, but only used in this method...","commit_id":"a0492f96bc610f3717870058ff5475d62a94fa76"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"9f8670be2878b4dda551abbcd4abc4fd0a573ea2","unresolved":false,"context_lines":[{"line_number":161,"context_line":"                                  else alarm.state)"},{"line_number":162,"context_line":"        RuleTarget.change_bool_op(evaluator.ALARM)"},{"line_number":163,"context_line":"        expression \u003d \u0027\u0027.join(self._logical_expression)"},{"line_number":164,"context_line":"        alarm_triggered \u003d eval(expression, globals(), self._rule_def_ns)"},{"line_number":165,"context_line":"        if alarm_triggered:"},{"line_number":166,"context_line":"            reason, reason_data \u003d self._reason(alarm, evaluator.ALARM)"},{"line_number":167,"context_line":"            self._refresh(alarm, evaluator.ALARM, reason, reason_data)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a68dd71_ae70d60b","line":164,"updated":"2016-01-25 19:52:21.000000000","message":"could we not copy/paste the logic we used in complex query or gnocchi query?","commit_id":"a0492f96bc610f3717870058ff5475d62a94fa76"},{"author":{"_account_id":8290,"name":"liusheng","email":"liusheng2048@gmail.com","username":"LiuSheng"},"change_message_id":"b816c0c799f04014b1066460ad4284a5cf3e27ab","unresolved":false,"context_lines":[{"line_number":161,"context_line":"                                  else alarm.state)"},{"line_number":162,"context_line":"        RuleTarget.change_bool_op(evaluator.ALARM)"},{"line_number":163,"context_line":"        expression \u003d \u0027\u0027.join(self._logical_expression)"},{"line_number":164,"context_line":"        alarm_triggered \u003d eval(expression, globals(), self._rule_def_ns)"},{"line_number":165,"context_line":"        if alarm_triggered:"},{"line_number":166,"context_line":"            reason, reason_data \u003d self._reason(alarm, evaluator.ALARM)"},{"line_number":167,"context_line":"            self._refresh(alarm, evaluator.ALARM, reason, reason_data)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a68dd71_2a8fdfcd","line":164,"in_reply_to":"9a68dd71_ae70d60b","updated":"2016-01-26 07:02:12.000000000","message":"you mean complex query transformer[1]? no, it cannot, the complex query related with sql expressions. here the eval() method will calculate the  logical expression of composite rule and implicitly invoke the bool() of every sub rule.\n\n[1] https://github.com/openstack/ceilometer/blob/master/ceilometer/storage/sqlalchemy/utils.py#L38","commit_id":"a0492f96bc610f3717870058ff5475d62a94fa76"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"9f8670be2878b4dda551abbcd4abc4fd0a573ea2","unresolved":false,"context_lines":[{"line_number":193,"context_line":"            return"},{"line_number":194,"context_line":"        LOG.debug(\"Evaluating composite rule alarm %s ...\", alarm.alarm_id)"},{"line_number":195,"context_line":"        self._reset_vars()"},{"line_number":196,"context_line":"        self._para_rules(alarm.rule)"},{"line_number":197,"context_line":"        insufficient \u003d self._evaluate_sufficient(alarm)"},{"line_number":198,"context_line":"        if insufficient:"},{"line_number":199,"context_line":"            # Evaluating all the rule if can not evaluate the composite rule"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a68dd71_4eefda1d","line":196,"updated":"2016-01-25 19:52:21.000000000","message":"what does _para_ mean?","commit_id":"a0492f96bc610f3717870058ff5475d62a94fa76"},{"author":{"_account_id":8290,"name":"liusheng","email":"liusheng2048@gmail.com","username":"LiuSheng"},"change_message_id":"b816c0c799f04014b1066460ad4284a5cf3e27ab","unresolved":false,"context_lines":[{"line_number":193,"context_line":"            return"},{"line_number":194,"context_line":"        LOG.debug(\"Evaluating composite rule alarm %s ...\", alarm.alarm_id)"},{"line_number":195,"context_line":"        self._reset_vars()"},{"line_number":196,"context_line":"        self._para_rules(alarm.rule)"},{"line_number":197,"context_line":"        insufficient \u003d self._evaluate_sufficient(alarm)"},{"line_number":198,"context_line":"        if insufficient:"},{"line_number":199,"context_line":"            # Evaluating all the rule if can not evaluate the composite rule"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a68dd71_ea66a728","line":196,"in_reply_to":"9a68dd71_4eefda1d","updated":"2016-01-26 07:02:12.000000000","message":"sorry, wrong spelling :(, I mean parse.","commit_id":"a0492f96bc610f3717870058ff5475d62a94fa76"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"f4316ae459233a716275b1ea66666082d079b15e","unresolved":false,"context_lines":[{"line_number":49,"context_line":"            self._evaluate()"},{"line_number":50,"context_line":"        if self.state \u003d\u003d evaluator.ALARM:"},{"line_number":51,"context_line":"            return True"},{"line_number":52,"context_line":"        return False"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    def _bool_eq_ok(self):"},{"line_number":55,"context_line":"        if not self.evaluated:"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a5de9d1_8f0a9d78","line":52,"updated":"2016-02-02 10:07:04.000000000","message":"return self.state \u003d\u003d evaluator.ALARM","commit_id":"365b399c38439da1ab3ad1aaa4178a9aea75614e"},{"author":{"_account_id":8290,"name":"liusheng","email":"liusheng2048@gmail.com","username":"LiuSheng"},"change_message_id":"0c6244e5af209d2a97562bf7fe11e74721b5b977","unresolved":false,"context_lines":[{"line_number":49,"context_line":"            self._evaluate()"},{"line_number":50,"context_line":"        if self.state \u003d\u003d evaluator.ALARM:"},{"line_number":51,"context_line":"            return True"},{"line_number":52,"context_line":"        return False"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    def _bool_eq_ok(self):"},{"line_number":55,"context_line":"        if not self.evaluated:"}],"source_content_type":"text/x-python","patch_set":11,"id":"5a5ae5dd_e2b47fd2","line":52,"in_reply_to":"7a5de9d1_8f0a9d78","updated":"2016-02-03 07:21:40.000000000","message":"Done","commit_id":"365b399c38439da1ab3ad1aaa4178a9aea75614e"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"f4316ae459233a716275b1ea66666082d079b15e","unresolved":false,"context_lines":[{"line_number":56,"context_line":"            self._evaluate()"},{"line_number":57,"context_line":"        if self.state \u003d\u003d evaluator.OK:"},{"line_number":58,"context_line":"            return True"},{"line_number":59,"context_line":"        return False"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    __nonzero__ \u003d _bool_eq_alarm"},{"line_number":62,"context_line":"    # compat Python3"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a5de9d1_8f813dc6","line":59,"updated":"2016-02-02 10:07:04.000000000","message":"return self.state \u003d\u003d evaluator.OK","commit_id":"365b399c38439da1ab3ad1aaa4178a9aea75614e"},{"author":{"_account_id":8290,"name":"liusheng","email":"liusheng2048@gmail.com","username":"LiuSheng"},"change_message_id":"0c6244e5af209d2a97562bf7fe11e74721b5b977","unresolved":false,"context_lines":[{"line_number":56,"context_line":"            self._evaluate()"},{"line_number":57,"context_line":"        if self.state \u003d\u003d evaluator.OK:"},{"line_number":58,"context_line":"            return True"},{"line_number":59,"context_line":"        return False"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    __nonzero__ \u003d _bool_eq_alarm"},{"line_number":62,"context_line":"    # compat Python3"}],"source_content_type":"text/x-python","patch_set":11,"id":"5a5ae5dd_c2af037c","line":59,"in_reply_to":"7a5de9d1_8f813dc6","updated":"2016-02-03 07:21:40.000000000","message":"Done","commit_id":"365b399c38439da1ab3ad1aaa4178a9aea75614e"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"f4316ae459233a716275b1ea66666082d079b15e","unresolved":false,"context_lines":[{"line_number":63,"context_line":"    __bool__ \u003d _bool_eq_alarm"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    @classmethod"},{"line_number":66,"context_line":"    def change_bool_op(cls, alarm_state):"},{"line_number":67,"context_line":"        if alarm_state \u003d\u003d evaluator.OK:"},{"line_number":68,"context_line":"            cls.__nonzero__ \u003d cls._bool_eq_ok"},{"line_number":69,"context_line":"            cls.__bool__ \u003d cls._bool_eq_ok"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a5de9d1_0ffb0d49","line":66,"updated":"2016-02-02 10:07:04.000000000","message":"This is just scary!","commit_id":"365b399c38439da1ab3ad1aaa4178a9aea75614e"},{"author":{"_account_id":8290,"name":"liusheng","email":"liusheng2048@gmail.com","username":"LiuSheng"},"change_message_id":"0c6244e5af209d2a97562bf7fe11e74721b5b977","unresolved":false,"context_lines":[{"line_number":63,"context_line":"    __bool__ \u003d _bool_eq_alarm"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    @classmethod"},{"line_number":66,"context_line":"    def change_bool_op(cls, alarm_state):"},{"line_number":67,"context_line":"        if alarm_state \u003d\u003d evaluator.OK:"},{"line_number":68,"context_line":"            cls.__nonzero__ \u003d cls._bool_eq_ok"},{"line_number":69,"context_line":"            cls.__bool__ \u003d cls._bool_eq_ok"}],"source_content_type":"text/x-python","patch_set":11,"id":"5a5ae5dd_e29d5f5a","line":66,"in_reply_to":"7a5de9d1_0ffb0d49","updated":"2016-02-03 07:21:40.000000000","message":"lol, sorry :(","commit_id":"365b399c38439da1ab3ad1aaa4178a9aea75614e"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"f4316ae459233a716275b1ea66666082d079b15e","unresolved":false,"context_lines":[{"line_number":83,"context_line":"        threshold_types \u003d (\u0027threshold\u0027, \u0027gnocchi_resources_threshold\u0027,"},{"line_number":84,"context_line":"                           \u0027gnocchi_aggregation_by_metrics_threshold\u0027,"},{"line_number":85,"context_line":"                           \u0027gnocchi_aggregation_by_resources_threshold\u0027)"},{"line_number":86,"context_line":"        RuleTarget.threshold_evaluators \u003d NamedExtensionManager("},{"line_number":87,"context_line":"            \u0027aodh.evaluator\u0027, threshold_types, invoke_on_load\u003dTrue,"},{"line_number":88,"context_line":"            invoke_args\u003d(self.conf,))"},{"line_number":89,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"7a5de9d1_afb9997b","line":86,"updated":"2016-02-02 10:07:04.000000000","message":"you\u0027re changing another class variable from another class? beuh :(\n\npass it as a constructor arg rather","commit_id":"365b399c38439da1ab3ad1aaa4178a9aea75614e"},{"author":{"_account_id":8290,"name":"liusheng","email":"liusheng2048@gmail.com","username":"LiuSheng"},"change_message_id":"0c6244e5af209d2a97562bf7fe11e74721b5b977","unresolved":false,"context_lines":[{"line_number":83,"context_line":"        threshold_types \u003d (\u0027threshold\u0027, \u0027gnocchi_resources_threshold\u0027,"},{"line_number":84,"context_line":"                           \u0027gnocchi_aggregation_by_metrics_threshold\u0027,"},{"line_number":85,"context_line":"                           \u0027gnocchi_aggregation_by_resources_threshold\u0027)"},{"line_number":86,"context_line":"        RuleTarget.threshold_evaluators \u003d NamedExtensionManager("},{"line_number":87,"context_line":"            \u0027aodh.evaluator\u0027, threshold_types, invoke_on_load\u003dTrue,"},{"line_number":88,"context_line":"            invoke_args\u003d(self.conf,))"},{"line_number":89,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"5a5ae5dd_82a34b9e","line":86,"in_reply_to":"7a5de9d1_afb9997b","updated":"2016-02-03 07:21:40.000000000","message":"Done","commit_id":"365b399c38439da1ab3ad1aaa4178a9aea75614e"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"fe59e82928b2b4d6a8e2c8be6808685fa6805fb5","unresolved":false,"context_lines":[{"line_number":130,"context_line":"            if rule.state \u003d\u003d new_state:"},{"line_number":131,"context_line":"                root_cause_rules.update({name: rule.rule})"},{"line_number":132,"context_line":"        reason_data.update(causative_rules\u003droot_cause_rules)"},{"line_number":133,"context_line":"        description \u003d {evaluator.ALARM: \u0027outside their threshold.\u0027,"},{"line_number":134,"context_line":"                       evaluator.OK: \u0027inside their threshold.\u0027,"},{"line_number":135,"context_line":"                       evaluator.UNKNOWN: \u0027state evaluated to unknown.\u0027}"},{"line_number":136,"context_line":"        params \u003d {\u0027state\u0027: new_state,"}],"source_content_type":"text/x-python","patch_set":11,"id":"5a5ae5dd_83eed689","line":133,"updated":"2016-02-03 15:26:15.000000000","message":"i would prefer if we moved this out. i don\u0027t like how we keep building this every single time. seems unnecesssary","commit_id":"365b399c38439da1ab3ad1aaa4178a9aea75614e"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"f4316ae459233a716275b1ea66666082d079b15e","unresolved":false,"context_lines":[{"line_number":158,"context_line":"                if rule.trending_state:"},{"line_number":159,"context_line":"                    rule.state \u003d (rule.trending_state if unknown"},{"line_number":160,"context_line":"                                  else alarm.state)"},{"line_number":161,"context_line":"        RuleTarget.change_bool_op(evaluator.ALARM)"},{"line_number":162,"context_line":"        expression \u003d \u0027\u0027.join(self._logical_expression)"},{"line_number":163,"context_line":"        alarm_triggered \u003d eval(expression, globals(), self._rule_def_ns)"},{"line_number":164,"context_line":"        if alarm_triggered:"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a5de9d1_fa02f108","line":161,"updated":"2016-02-02 10:07:04.000000000","message":"I read that and I\u0027m like WTF is he changing the __bool__ attribute of another class, I just… don\u0027t see the point? Is this thread safe? is this just… insanity!? :)","commit_id":"365b399c38439da1ab3ad1aaa4178a9aea75614e"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"aad9e2acef7e48d948e6eebd99bdb0c88713f315","unresolved":false,"context_lines":[{"line_number":158,"context_line":"                if rule.trending_state:"},{"line_number":159,"context_line":"                    rule.state \u003d (rule.trending_state if unknown"},{"line_number":160,"context_line":"                                  else alarm.state)"},{"line_number":161,"context_line":"        RuleTarget.change_bool_op(evaluator.ALARM)"},{"line_number":162,"context_line":"        expression \u003d \u0027\u0027.join(self._logical_expression)"},{"line_number":163,"context_line":"        alarm_triggered \u003d eval(expression, globals(), self._rule_def_ns)"},{"line_number":164,"context_line":"        if alarm_triggered:"}],"source_content_type":"text/x-python","patch_set":11,"id":"5a5ae5dd_6fcd8f5c","line":161,"in_reply_to":"7a5de9d1_fa02f108","updated":"2016-02-04 10:00:41.000000000","message":"Strongly agreed","commit_id":"365b399c38439da1ab3ad1aaa4178a9aea75614e"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"53cf09e3c7ce6b122a361062071a4ae56465060f","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        self.rule_num \u003d 0"},{"line_number":99,"context_line":"        self._user_expression \u003d None"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    def _parse_composite_rule(self, alarm_rule):"},{"line_number":102,"context_line":"        \"\"\"Parse the composite rule to a logical expression."},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"        The composite rule is assembled by sub threshold rules with \u0027and\u0027,"}],"source_content_type":"text/x-python","patch_set":13,"id":"5a5ae5dd_6f47cf1d","line":101,"updated":"2016-02-04 09:59:44.000000000","message":"Using recursive method to do this limit the depth of dict to something like 255 in python by default.\n\nAnyways, I pretty sure that is not an issue for aodh.","commit_id":"2ae3756497aea1a7d2986be8a71c26021d65ea40"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"53cf09e3c7ce6b122a361062071a4ae56465060f","unresolved":false,"context_lines":[{"line_number":204,"context_line":"                return item"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        expression_ok \u003d \u0027\u0027.join(map(_swap_all_any, self._logical_expression))"},{"line_number":207,"context_line":"        ok_result \u003d eval(expression_ok, globals(), self._rule_def_ns)"},{"line_number":208,"context_line":"        if ok_result:"},{"line_number":209,"context_line":"            reason, reason_data \u003d self._reason(alarm, evaluator.OK)"},{"line_number":210,"context_line":"            self._refresh(alarm, evaluator.OK, reason, reason_data)"}],"source_content_type":"text/x-python","patch_set":13,"id":"5a5ae5dd_a46e4ec7","line":207,"updated":"2016-02-04 09:59:44.000000000","message":"I\u0027m not very comfortable to use eval for this. I don\u0027t see why this is strongly required ?\n\nThe whole code write python code into a string and they eval it. Why not just write python code that evaluate the expression.\n\nThe combinaison is just a pile of dict. \nWhat about using your idea for evaluating alarm_rule (the boolean object AlarmTarget) for each operators (\"and\" and \"or\"), that take the alarm list in __init__ and implements __bool__ too.\n\nSo you will get a structure like bellow instead of an insecure string:\n\n  expr \u003d AndTarget([AlarmTarget(..), AlarmTarget(), OrTarget(...)])\n\nand to evaluate the thing just do:\n\n  ok_result \u003d bool(expr) \n\nthen all __bool__ methods will be evaluated and no eval are used.","commit_id":"2ae3756497aea1a7d2986be8a71c26021d65ea40"},{"author":{"_account_id":8290,"name":"liusheng","email":"liusheng2048@gmail.com","username":"LiuSheng"},"change_message_id":"3bf2880b57b56e71eaac84dfd3acafa6b715767b","unresolved":false,"context_lines":[{"line_number":204,"context_line":"                return item"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        expression_ok \u003d \u0027\u0027.join(map(_swap_all_any, self._logical_expression))"},{"line_number":207,"context_line":"        ok_result \u003d eval(expression_ok, globals(), self._rule_def_ns)"},{"line_number":208,"context_line":"        if ok_result:"},{"line_number":209,"context_line":"            reason, reason_data \u003d self._reason(alarm, evaluator.OK)"},{"line_number":210,"context_line":"            self._refresh(alarm, evaluator.OK, reason, reason_data)"}],"source_content_type":"text/x-python","patch_set":13,"id":"5a5ae5dd_730d753d","line":207,"in_reply_to":"5a5ae5dd_a46e4ec7","updated":"2016-02-04 13:42:03.000000000","message":"Hi sileht, the idea with eval() for rule evaluation is mainly because I want to support short-circuit logic in composite rule evaluation. e.g. we have a composite rule like *all([rule0,rule1,any([rule2,rule3,rule4,rule5,])])*, if we have evaluated rule0 as OK state, we can determine the whole composite rule as OK state, whether others sub rules are OK or ALARM. and we don\u0027t need to evaluate evaluate every sub rule.\n\nyour suggestion is cool, thanks for teaching me! I will try.","commit_id":"2ae3756497aea1a7d2986be8a71c26021d65ea40"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"bd3752bd87798762d27f77c4cf48518840cbf6d8","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"COMPARATORS \u003d {\u0027and\u0027: \u0027all\u0027, \u0027or\u0027: \u0027any\u0027}"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"STATE_CHANGE \u003d {evaluator.ALARM: \u0027outside their threshold.\u0027,"},{"line_number":27,"context_line":"                evaluator.OK: \u0027inside their threshold.\u0027,"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_09eb76b1","line":24,"updated":"2016-02-16 13:31:35.000000000","message":"Seems unused.","commit_id":"99d493190f8a96db8309bf46237d19759cb1f8d4"},{"author":{"_account_id":8290,"name":"liusheng","email":"liusheng2048@gmail.com","username":"LiuSheng"},"change_message_id":"a6bf03756998d9b486211c1fc0725a675285a6a7","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"COMPARATORS \u003d {\u0027and\u0027: \u0027all\u0027, \u0027or\u0027: \u0027any\u0027}"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"STATE_CHANGE \u003d {evaluator.ALARM: \u0027outside their threshold.\u0027,"},{"line_number":27,"context_line":"                evaluator.OK: \u0027inside their threshold.\u0027,"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_356ee896","line":24,"in_reply_to":"dae33548_09eb76b1","updated":"2016-02-19 02:16:55.000000000","message":"Done","commit_id":"99d493190f8a96db8309bf46237d19759cb1f8d4"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"bd3752bd87798762d27f77c4cf48518840cbf6d8","unresolved":false,"context_lines":[{"line_number":54,"context_line":"    def __init__(self, rule_target):"},{"line_number":55,"context_line":"        self.rule_target \u003d rule_target"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def _bool_op(self):"},{"line_number":58,"context_line":"        self.rule_target.evaluate()"},{"line_number":59,"context_line":"        return self.rule_target.state \u003d\u003d evaluator.OK"},{"line_number":60,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_8945c6b4","line":57,"updated":"2016-02-16 13:31:35.000000000","message":"Just define this as __bool__ and then __nonzero__ \u003d __bool__\n\nIt\u0027s just a nit, but that\u0027ll remove you a line and one indirection :)","commit_id":"99d493190f8a96db8309bf46237d19759cb1f8d4"},{"author":{"_account_id":8290,"name":"liusheng","email":"liusheng2048@gmail.com","username":"LiuSheng"},"change_message_id":"a6bf03756998d9b486211c1fc0725a675285a6a7","unresolved":false,"context_lines":[{"line_number":54,"context_line":"    def __init__(self, rule_target):"},{"line_number":55,"context_line":"        self.rule_target \u003d rule_target"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def _bool_op(self):"},{"line_number":58,"context_line":"        self.rule_target.evaluate()"},{"line_number":59,"context_line":"        return self.rule_target.state \u003d\u003d evaluator.OK"},{"line_number":60,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_75687088","line":57,"in_reply_to":"dae33548_8945c6b4","updated":"2016-02-19 02:16:55.000000000","message":"Done","commit_id":"99d493190f8a96db8309bf46237d19759cb1f8d4"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"bd3752bd87798762d27f77c4cf48518840cbf6d8","unresolved":false,"context_lines":[{"line_number":65,"context_line":"    __bool__ \u003d _bool_op"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"class AlarmEvaluation(object):"},{"line_number":69,"context_line":"    def __init__(self, rule_target):"},{"line_number":70,"context_line":"        self.rule_target \u003d rule_target"},{"line_number":71,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_a9788af3","line":68,"updated":"2016-02-16 13:31:35.000000000","message":"This is exactly the same code than OkEvaluation except one field. Define a parent class, and just inherit from it. :)","commit_id":"99d493190f8a96db8309bf46237d19759cb1f8d4"},{"author":{"_account_id":8290,"name":"liusheng","email":"liusheng2048@gmail.com","username":"LiuSheng"},"change_message_id":"a6bf03756998d9b486211c1fc0725a675285a6a7","unresolved":false,"context_lines":[{"line_number":65,"context_line":"    __bool__ \u003d _bool_op"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"class AlarmEvaluation(object):"},{"line_number":69,"context_line":"    def __init__(self, rule_target):"},{"line_number":70,"context_line":"        self.rule_target \u003d rule_target"},{"line_number":71,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_150e44e5","line":68,"in_reply_to":"dae33548_a9788af3","updated":"2016-02-19 02:16:55.000000000","message":"Done","commit_id":"99d493190f8a96db8309bf46237d19759cb1f8d4"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"bd3752bd87798762d27f77c4cf48518840cbf6d8","unresolved":false,"context_lines":[{"line_number":144,"context_line":"                and list(alarm_rule)[0] in (\u0027and\u0027, \u0027or\u0027)):"},{"line_number":145,"context_line":"            and_or_key \u003d list(alarm_rule)[0]"},{"line_number":146,"context_line":"            if and_or_key \u003d\u003d \u0027and\u0027:"},{"line_number":147,"context_line":"                rules \u003d [self._parse_composite_rule(r) for r in"},{"line_number":148,"context_line":"                         alarm_rule[\u0027and\u0027]]"},{"line_number":149,"context_line":"                rules_alarm, rules_ok \u003d zip(*rules)"},{"line_number":150,"context_line":"                return AndOp(rules_alarm), OrOp(rules_ok)"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_e963b218","line":147,"updated":"2016-02-16 13:31:35.000000000","message":"I think you can build a generator rather than a list – replace [ ] by ( ), so it you avoid constructing the list before calling zip() – should be more efficient for long list of rules.","commit_id":"99d493190f8a96db8309bf46237d19759cb1f8d4"},{"author":{"_account_id":8290,"name":"liusheng","email":"liusheng2048@gmail.com","username":"LiuSheng"},"change_message_id":"a6bf03756998d9b486211c1fc0725a675285a6a7","unresolved":false,"context_lines":[{"line_number":144,"context_line":"                and list(alarm_rule)[0] in (\u0027and\u0027, \u0027or\u0027)):"},{"line_number":145,"context_line":"            and_or_key \u003d list(alarm_rule)[0]"},{"line_number":146,"context_line":"            if and_or_key \u003d\u003d \u0027and\u0027:"},{"line_number":147,"context_line":"                rules \u003d [self._parse_composite_rule(r) for r in"},{"line_number":148,"context_line":"                         alarm_rule[\u0027and\u0027]]"},{"line_number":149,"context_line":"                rules_alarm, rules_ok \u003d zip(*rules)"},{"line_number":150,"context_line":"                return AndOp(rules_alarm), OrOp(rules_ok)"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_155764cb","line":147,"in_reply_to":"dae33548_e963b218","updated":"2016-02-19 02:16:55.000000000","message":"Done","commit_id":"99d493190f8a96db8309bf46237d19759cb1f8d4"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"bd3752bd87798762d27f77c4cf48518840cbf6d8","unresolved":false,"context_lines":[{"line_number":149,"context_line":"                rules_alarm, rules_ok \u003d zip(*rules)"},{"line_number":150,"context_line":"                return AndOp(rules_alarm), OrOp(rules_ok)"},{"line_number":151,"context_line":"            else:"},{"line_number":152,"context_line":"                rules \u003d [self._parse_composite_rule(r) for r in"},{"line_number":153,"context_line":"                         alarm_rule[\u0027or\u0027]]"},{"line_number":154,"context_line":"                rules_alarm, rules_ok \u003d zip(*rules)"},{"line_number":155,"context_line":"                return OrOp(rules_alarm), AndOp(rules_ok)"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_0971b6e0","line":152,"updated":"2016-02-16 13:31:35.000000000","message":"ditto","commit_id":"99d493190f8a96db8309bf46237d19759cb1f8d4"},{"author":{"_account_id":8290,"name":"liusheng","email":"liusheng2048@gmail.com","username":"LiuSheng"},"change_message_id":"a6bf03756998d9b486211c1fc0725a675285a6a7","unresolved":false,"context_lines":[{"line_number":149,"context_line":"                rules_alarm, rules_ok \u003d zip(*rules)"},{"line_number":150,"context_line":"                return AndOp(rules_alarm), OrOp(rules_ok)"},{"line_number":151,"context_line":"            else:"},{"line_number":152,"context_line":"                rules \u003d [self._parse_composite_rule(r) for r in"},{"line_number":153,"context_line":"                         alarm_rule[\u0027or\u0027]]"},{"line_number":154,"context_line":"                rules_alarm, rules_ok \u003d zip(*rules)"},{"line_number":155,"context_line":"                return OrOp(rules_alarm), AndOp(rules_ok)"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_b56158ab","line":152,"in_reply_to":"dae33548_0971b6e0","updated":"2016-02-19 02:16:55.000000000","message":"Done","commit_id":"99d493190f8a96db8309bf46237d19759cb1f8d4"}],"aodh/tests/unit/evaluator/test_composite.py":[{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"9f8670be2878b4dda551abbcd4abc4fd0a573ea2","unresolved":false,"context_lines":[{"line_number":221,"context_line":"                 granularity, value] for value in values]"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"    @staticmethod"},{"line_number":224,"context_line":"    def _reason(new_state, user_expression, causative_rules\u003d(),"},{"line_number":225,"context_line":"                transition\u003dTrue):"},{"line_number":226,"context_line":"        root_cause_rules \u003d {}"},{"line_number":227,"context_line":"        for index, rule in causative_rules:"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a68dd71_0eea4274","line":224,"updated":"2016-01-25 19:52:21.000000000","message":"seems very strange we are duplicating real code here.","commit_id":"a0492f96bc610f3717870058ff5475d62a94fa76"},{"author":{"_account_id":8290,"name":"liusheng","email":"liusheng2048@gmail.com","username":"LiuSheng"},"change_message_id":"b816c0c799f04014b1066460ad4284a5cf3e27ab","unresolved":false,"context_lines":[{"line_number":221,"context_line":"                 granularity, value] for value in values]"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"    @staticmethod"},{"line_number":224,"context_line":"    def _reason(new_state, user_expression, causative_rules\u003d(),"},{"line_number":225,"context_line":"                transition\u003dTrue):"},{"line_number":226,"context_line":"        root_cause_rules \u003d {}"},{"line_number":227,"context_line":"        for index, rule in causative_rules:"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a68dd71_4f290a9a","line":224,"in_reply_to":"9a68dd71_0eea4274","updated":"2016-01-26 07:02:12.000000000","message":"yes... but this can also reflect what we want to test :)","commit_id":"a0492f96bc610f3717870058ff5475d62a94fa76"}]}
