diff --git a/diag_cmd.py b/diag_cmd.py index ccca161d..1ffa72f0 100644 --- a/diag_cmd.py +++ b/diag_cmd.py @@ -22,6 +22,7 @@ import sys import textwrap import re +import json from uuid import uuid1 as uuid, UUID from optparse import OptionParser, BadOptionError, Option, IndentedHelpFormatter from core import ObdiagHome @@ -867,8 +868,61 @@ def __init__(self): super(ObdiagRCARunCommand, self).__init__('run', 'root cause analysis') self.parser.add_option('--scene', type='string', help="rca scene name. The argument is required.") self.parser.add_option('--store_dir', type='string', help='the dir to store rca result, current dir by default.', default='./rca/') - self.parser.add_option('--input_parameters', type='string', help='input parameters of scene') + self.parser.add_option('--input_parameters', action='callback', type='string', callback=self._input_parameters_scene, help='input parameters of scene') self.parser.add_option('-c', type='string', help='obdiag custom config', default=os.path.expanduser('~/.obdiag/config.yml')) + self.scene_input_param_map = {} + + def _input_parameters_scene(self, option, opt_str, value, parser): + """ + input parameters of scene + """ + try: + # input_parameters option is json format + try: + self.scene_input_param_map = json.loads(value) + return + except Exception as e: + # raise Exception("Failed to parse input_parameters. Please check the option is json:{0}".format(value)) + ROOT_IO.verbose("input_parameters option {0} is not json.".format(value)) + + # input_parameters option is key=val format + key, val = value.split('=', 1) + if key is None or key == "": + return + m = self._input_parameters_scene_set(key, val) + + def _scene_input_param(param_map, scene_param_map): + for scene_param_map_key, scene_param_map_value in scene_param_map.items(): + if scene_param_map_key in param_map: + if isinstance(scene_param_map_value, dict): + _scene_input_param(param_map[scene_param_map_key], scene_param_map_value) + else: + param_map[scene_param_map_key] = scene_param_map_value + else: + param_map[scene_param_map_key] = scene_param_map_value + return param_map + + self.scene_input_param_map = _scene_input_param(self.scene_input_param_map, m) + except Exception as e: + raise Exception("Key or val ({1}) is illegal: {0}".format(e, value)) + + def _input_parameters_scene_set(self, key, val): + def recursion(param_map, key, val): + if key is None or key == "": + raise Exception("key is None") + if val is None or val == "": + raise Exception("val is None") + if key.startswith(".") or key.endswith("."): + raise Exception("Key starts or ends '.'") + if "." in key: + map_key = key.split(".")[0] + param_map[map_key] = recursion({}, key[len(map_key) + 1 :], val) + return param_map + else: + param_map[key] = val + return param_map + + return recursion({}, key, val) def init(self, cmd, args): super(ObdiagRCARunCommand, self).init(cmd, args) @@ -876,6 +930,7 @@ def init(self, cmd, args): return self def _do_command(self, obdiag): + Util.set_option(self.opts, 'input_parameters', self.scene_input_param_map) return obdiag.rca_run(self.opts) diff --git a/handler/rca/rca_handler.py b/handler/rca/rca_handler.py index 993bd173..4699c37d 100644 --- a/handler/rca/rca_handler.py +++ b/handler/rca/rca_handler.py @@ -113,7 +113,6 @@ def __init__(self, context): all_scenes_info, all_scenes_item = rca_list.get_all_scenes() self.context.set_variable("rca_deep_limit", len(all_scenes_info)) self.all_scenes = all_scenes_item - self.rca_scene_parameters = None self.rca_scene = None self.cluster = self.context.get_variable("ob_cluster") self.nodes = self.context.get_variable("observer_nodes") @@ -122,15 +121,7 @@ def __init__(self, context): # init input parameters self.report = None self.tasks = None - rca_scene_parameters = Util.get_option(self.options, "input_parameters", "") - if rca_scene_parameters != "": - try: - rca_scene_parameters = json.loads(rca_scene_parameters) - except Exception as e: - raise Exception("Failed to parse input_parameters. Please check the option is json:{0}".format(rca_scene_parameters)) - else: - rca_scene_parameters = {} - self.context.set_variable("input_parameters", rca_scene_parameters) + self.context.set_variable("input_parameters", Util.get_option(self.options, "input_parameters")) self.store_dir = Util.get_option(self.options, "store_dir", "./rca/") self.context.set_variable("store_dir", self.store_dir) self.stdio.verbose( diff --git a/handler/rca/scene/ddl_disk_full_scene.py b/handler/rca/scene/ddl_disk_full_scene.py index 31da106a..71c5d90d 100644 --- a/handler/rca/scene/ddl_disk_full_scene.py +++ b/handler/rca/scene/ddl_disk_full_scene.py @@ -132,7 +132,11 @@ def execute(self): ## if the action is add_index sql = "select table_id from oceanbase.__all_virtual_table_history where tenant_id = '{0}' and data_table_id = '{1}' and table_name like '%{2}%';".format(self.tenant_id, self.table_id, self.index_name) self.verbose("execute_sql is {0}".format(sql)) - self.index_table_id = self.ob_connector.execute_sql_return_cursor_dictionary(sql).fetchall()[0]["table_id"] + sql_tables_data = self.ob_connector.execute_sql_return_cursor_dictionary(sql).fetchall() + if len(sql_tables_data) == 0: + self.stdio.error("can not find index table id by index name: {0}. Please check the index name.".format(self.index_name)) + return + self.index_table_id = sql_tables_data[0]["table_id"] self.verbose("index_table_id is {0}".format(self.index_table_id)) self.record.add_record("index_table_id is {0}".format(self.index_table_id))