def test_related_metrics(self): rm = alarm_expr_parser.AlarmExprParser(self.expr2).related_metrics e_result = [] e_result.append({'name': 'foo', 'dimensions': {}}) self.assertEqual(e_result, rm) rm = alarm_expr_parser.AlarmExprParser(self.expr1).related_metrics self.assertEqual(3, len(rm))
def test_func(self): expr = alarm_expr_parser.AlarmExprParser(self.expr1).parse_result self.assertEqual( "max", expr.sub_expr_list[1].sub_expr_list[1].func.encode('utf8')) expr = alarm_expr_parser.AlarmExprParser(self.expr2).parse_result self.assertEqual("max", expr.func.encode('utf8'))
def test_periods(self): expr = alarm_expr_parser.AlarmExprParser(self.expr1).parse_result self.assertEqual( 1, int(expr.sub_expr_list[1].sub_expr_list[1].periods.encode('utf8'))) expr = alarm_expr_parser.AlarmExprParser(self.expr2).parse_result self.assertEqual(10, int(expr.periods))
def test_operator(self): expr = alarm_expr_parser.AlarmExprParser(self.expr1).parse_result self.assertEqual( 'GT', expr.sub_expr_list[1].sub_expr_list[1].normalized_operator.encode( 'utf8')) expr = alarm_expr_parser.AlarmExprParser(self.expr2).parse_result self.assertEqual('>=', expr.operator)
def test_threshold(self): expr = alarm_expr_parser.AlarmExprParser(self.expr1).parse_result self.assertEqual( 100, float(expr.sub_expr_list[1].sub_expr_list[1].threshold.encode( 'utf8'))) expr = alarm_expr_parser.AlarmExprParser(self.expr2).parse_result self.assertEqual(100, float(expr.threshold))
def test_dimensions_list(self): expr = alarm_expr_parser.AlarmExprParser(self.expr0).parse_result temp = [] for e in expr.sub_expr_list[0].dimensions_as_list: temp.append(e.encode('utf8')) self.assertEqual(['घोड़ा=馬', 'dn2=dv2', '千幸福的笑脸घ=千幸福的笑脸घ'], temp) expr = alarm_expr_parser.AlarmExprParser(self.expr2).parse_result self.assertEqual([], expr.dimensions_as_list)
def test_wrong_input(self): expr = alarm_expr_parser.AlarmExprParser(self.expr3).parse_result self.assertEqual(None, expr) expr = alarm_expr_parser.AlarmExprParser(self.expr4).parse_result self.assertEqual(None, expr) expr = alarm_expr_parser.AlarmExprParser(self.expr5).parse_result self.assertEqual(None, expr) expr = alarm_expr_parser.AlarmExprParser(self.expr6).parse_result self.assertEqual(None, expr) expr = alarm_expr_parser.AlarmExprParser(self.expr7).parse_result self.assertEqual(None, expr)
def test_expr(self): expr = alarm_expr_parser.AlarmExprParser(self.expr0).parse_result self.assertEqual( "max(-_.千幸福的笑脸{घोड़ा=馬," "dn2=dv2,千幸福的笑脸घ=千幸福的笑脸घ})gte100" "times3", expr.sub_expr_list[0].sub_expr_str.encode('utf8')) self.assertEqual( "sum(biz{dn5=dv58})>99", expr.sub_expr_list[1].sub_expr_list[1]. sub_expr_list[0].sub_expr_str.encode('utf8')) expr = alarm_expr_parser.AlarmExprParser(self.expr2).parse_result self.assertEqual("max(foo)>=100times10", expr.sub_expr_str.encode('utf8'))
def test_dimensions_dict(self): expr = alarm_expr_parser.AlarmExprParser(self.expr0).parse_result temp = {} od = expr.sub_expr_list[0].dimensions_as_dict for e in od.keys(): temp[e.encode('utf8')] = od[e].encode('utf8') self.assertEqual({ 'घोड़ा': '馬', 'dn2': 'dv2', '千幸福的笑脸घ': '千幸福的笑脸घ' }, temp) expr = alarm_expr_parser.AlarmExprParser(self.expr2).parse_result self.assertEqual({}, expr.dimensions_as_dict)
def test_logic(self): expr = alarm_expr_parser.AlarmExprParser(self.expr0).parse_result self.assertEqual(u'AND', expr.logic_operator) self.assertEqual(None, expr.sub_expr_list[0].logic_operator) self.assertEqual(u'OR', expr.sub_expr_list[1].logic_operator) self.assertEqual(u'AND', expr.sub_expr_list[1].sub_expr_list[1].logic_operator) expr = alarm_expr_parser.AlarmExprParser(self.expr1).parse_result self.assertEqual(u'AND', expr.logic_operator) self.assertEqual('OR', expr.sub_expr_list[1].logic_operator) self.assertEqual(None, expr.sub_expr_list[0].logic_operator) self.assertEqual( 'max(foo{hostname=mini-mon,千=千}, 120) > 100'.decode('utf8'), expr.sub_expr_list[0].fmtd_sub_expr_str) expr = alarm_expr_parser.AlarmExprParser(self.expr2).parse_result self.assertEqual(None, expr.logic_operator)
def is_valid_alarm_definition(alarm_def_json): alarm_definition = json.loads(alarm_def_json) for key in key_set: if key not in alarm_definition: return False expression = alarm_definition['expression'] alarm_parser = parser.AlarmExprParser(expression) if not alarm_parser.parse_result: return False return True
def is_valid_update_alarm_definition(ori_alarm_def_json, new_alarm_def_json): # both should be valid alarm definition if (not (is_valid_alarm_definition(ori_alarm_def_json) and is_valid_alarm_definition(new_alarm_def_json))): return False ori_alarm_definition = json.loads(ori_alarm_def_json) new_alarm_definition = json.loads(new_alarm_def_json) # match_by should not change if ori_alarm_definition['match_by'] != new_alarm_definition['match_by']: return False ori_expression = ori_alarm_definition['expression'] ori_alarm_parser = parser.AlarmExprParser(ori_expression) ori_sub_expr_list = ori_alarm_parser.sub_expr_list new_expression = new_alarm_definition['expression'] new_alarm_parser = parser.AlarmExprParser(new_expression) new_sub_expr_list = new_alarm_parser.sub_expr_list # should have same number of sub alarm exprs l = len(ori_sub_expr_list) if not new_sub_expr_list or l != len(new_sub_expr_list): return False for i in range(l): sub_expr_ori = ori_sub_expr_list[i] sub_expr_new = new_sub_expr_list[i] # each metrics in alarm expr should remain the same if (sub_expr_ori.normalized_metric_name != sub_expr_new.normalized_metric_name): return False if (sub_expr_ori.dimensions_as_dict != sub_expr_new.dimensions_as_dict): return False return True
def update_thresh_processor(self, alarm_def): """Update the processor with updated alarm definition.""" def update_data(): # inherit previous stored metrics values for name in self.expr_data_queue: ts = tu.utcnow_ts() new_expr_data_queue[name] = { 'data': {}, 'state': 'UNDETERMINED', 'create_timestamp': self.expr_data_queue[name]['create_timestamp'], 'update_timestamp': ts, 'state_update_timestamp': self.expr_data_queue[name]['state_update_timestamp'] } for i in range(0, len(new_sub_expr_list), 1): expr_old = self.sub_expr_list[i].fmtd_sub_expr_str expr_new = new_sub_expr_list[i].fmtd_sub_expr_str new_expr_data_queue[name]['data'][expr_new] = { 'state': 'UNDETERMINED', 'metrics': (self.expr_data_queue[name]['data'] [expr_old]['metrics']), 'values': [] } LOG.debug('update ThresholdProcessor!') new_alarm_definition = alarm_def new_expression = new_alarm_definition['expression'] alarm_parser = parser.AlarmExprParser(new_expression) new_sub_expr_list = alarm_parser.sub_expr_list new_expr_data_queue = {} update_data() self.expr_data_queue = new_expr_data_queue self.sub_expr_list = new_sub_expr_list self.sub_alarm_expr = alarm_parser.sub_alarm_expressions self.parse_result = alarm_parser.parse_result self.alarm_definition = new_alarm_definition self.expression = new_expression self.match_by = self.alarm_definition['match_by'] if '' in self.match_by: self.match_by.remove('') if len(self.match_by) == 0: self.match_by = None LOG.debug('successfully update ThresholdProcessor!') return True
def __init__(self, alarm_def): """One processor instance hold one alarm definition.""" LOG.debug('initializing ThresholdProcessor!') super(ThresholdProcessor, self).__init__() self.alarm_definition = alarm_def self.expression = self.alarm_definition['expression'] self.match_by = self.alarm_definition['match_by'] self.expr_data_queue = {} self.related_metrics = {} if len(self.match_by) == 0: self.match_by = None alarm_parser = parser.AlarmExprParser(self.expression) self.parse_result = alarm_parser.parse_result self.sub_expr_list = alarm_parser.sub_expr_list self.related_metrics[None] = alarm_parser.related_metrics self.sub_alarm_expr = alarm_parser.sub_alarm_expressions LOG.debug('successfully initialize ThresholdProcessor!')
def do_post_alarm_definitions(self, req, res): LOG.debug('Creating the alarm definitions') msg = req.stream.read() LOG.debug("Message: %s" % msg) post_msg = ast.literal_eval(msg) # random uuid generation for alarm definition id = str(uuid.uuid4()) post_msg["id"] = id post_msg = AlarmDefinitionUtil.severityparsing(post_msg) post_msg_json = json.dumps(post_msg) LOG.debug("Validating Alarm Definition Data: %s" % post_msg_json) if alarm_expr_validator.is_valid_alarm_definition(post_msg_json): LOG.debug("Post Alarm Definition method: %s" % post_msg) try: expression_parsed = (alarm_expr_parser.AlarmExprParser( post_msg["expression"])) expression_data = expression_parsed.sub_alarm_expressions expression_data_list = [] for temp in expression_data: expression_data_list.append(expression_data[temp]) post_msg["expression_data"] = expression_data_list LOG.debug(post_msg) es_res = self._es_conn.post_messages(json.dumps(post_msg), id) LOG.debug('Query to ElasticSearch returned Status: %s' % es_res) res.status = getattr(falcon, 'HTTP_%s' % es_res) except Exception: LOG.exception('Error occurred while handling ' 'Alarm Definition Post Request.') res.status = getattr(falcon, 'HTTP_400') else: LOG.error('Alarm definition is not valid.') res.status = getattr(falcon, 'HTTP_400')
def test_metric_name(self): expr = alarm_expr_parser.AlarmExprParser(self.expr1).parse_result self.assertEqual( 'biz', expr.sub_expr_list[1].sub_expr_list[1].metric_name.encode('utf8'))
def do_put_alarm_definitions(self, req, res, id): LOG.debug("Put the alarm definitions with id: %s" % id) es_res = self._es_conn.get_message_by_id(id) LOG.debug('Query to ElasticSearch returned Status: %s' % es_res.status_code) es_res = self._get_alarm_definitions_response(es_res) LOG.debug('Query to ElasticSearch returned: %s' % es_res) original_data = {} try: if es_res["hits"]: res_data = es_res["hits"][0] if res_data: original_data = json.dumps({ "id": id, "name": res_data["_source"]["name"], "description": res_data["_source"]["description"], "expression": res_data["_source"]["expression"], "expression_data": res_data["_source"]["expression_data"], "severity": res_data["_source"]["severity"], "match_by": res_data["_source"]["match_by"], "alarm_actions": res_data["_source"]["alarm_actions"], "ok_actions": res_data["_source"]["ok_actions"], "undetermined_actions": res_data["_source"]["undetermined_actions"] }) msg = req.stream.read() put_msg = ast.literal_eval(msg) put_msg = AlarmDefinitionUtil.severityparsing(put_msg) expression_parsed = (alarm_expr_parser.AlarmExprParser( put_msg["expression"])) expression_data = expression_parsed.sub_alarm_expressions expression_data_list = [] for temp in expression_data: expression_data_list.append(expression_data[temp]) put_msg["expression_data"] = expression_data_list put_msg_json = json.dumps(put_msg) LOG.debug("Alarm Definition Put Data: %s" % put_msg_json) if alarm_expr_validator.is_valid_update_alarm_definition( original_data, put_msg_json): es_res = self._es_conn.put_messages(put_msg_json, id) LOG.debug('Query to ElasticSearch returned Status: %s' % es_res) res.status = getattr(falcon, 'HTTP_%s' % es_res) else: res.status = getattr(falcon, 'HTTP_400') LOG.debug("Validating Alarm Definition Failed !!") except Exception: LOG.exception('Error occurred while handling Alarm ' 'Definition Put Request.')
def test_wrong_format_expr(self): sub_expr_list = (alarm_expr_parser.AlarmExprParser( self.expr8).sub_expr_list) self.assertEqual(None, sub_expr_list)
def test_sub_alarm_expressions(self): sae = (alarm_expr_parser.AlarmExprParser( self.expr1).sub_alarm_expressions) print(sae) self.assertEqual(3, len(sae))
def test_sub_expr_list(self): expr = alarm_expr_parser.AlarmExprParser(self.expr2).parse_result temp = expr.sub_expr_list self.assertEqual([], temp)
def test_dimensions_str(self): expr = alarm_expr_parser.AlarmExprParser(self.expr2).parse_result temp = expr.dimensions_str self.assertEqual('', temp)