Improve the CM shell client alarm visualisation
This change aim to get a better alarm representation in shell. In alarm-list: * it add a short sentence to describe the alarm rule * it remove project_id/user_id because it always show the same id for all alarm for end-user In alarm-show, it show alarm rule attributes as alarm properties instead of a unparsable json in the rule property. example of short sentence for column 'Alarm condition': * combinated states (AND) of 8babd6a2-c457-42d0-9eb5-cdfb3cb50203, d0e11a94-8f59-48a9-8f6d-b0d68aaac8d0 * cpu_util >= 50.0 during 1 x 60s Change-Id: If4df2dc08f9f4cb7796fd98308c7d62e311d1138
This commit is contained in:
		| @@ -63,17 +63,19 @@ def print_dict(d, dict_property="Property", wrap=0): | |||||||
|         # convert dict to str to check length |         # convert dict to str to check length | ||||||
|         if isinstance(v, dict): |         if isinstance(v, dict): | ||||||
|             v = str(v) |             v = str(v) | ||||||
|         if wrap > 0: |  | ||||||
|             v = textwrap.fill(str(v), wrap) |  | ||||||
|         # if value has a newline, add in multiple rows |         # if value has a newline, add in multiple rows | ||||||
|         # e.g. fault with stacktrace |         # e.g. fault with stacktrace | ||||||
|         if v and isinstance(v, basestring) and r'\n' in v: |         if v and isinstance(v, basestring) and r'\n' in v: | ||||||
|             lines = v.strip().split(r'\n') |             lines = v.strip().split(r'\n') | ||||||
|             col1 = k |             col1 = k | ||||||
|             for line in lines: |             for line in lines: | ||||||
|  |                 if wrap > 0: | ||||||
|  |                     line = textwrap.fill(str(line), wrap) | ||||||
|                 pt.add_row([col1, line]) |                 pt.add_row([col1, line]) | ||||||
|                 col1 = '' |                 col1 = '' | ||||||
|         else: |         else: | ||||||
|  |             if wrap > 0: | ||||||
|  |                 v = textwrap.fill(str(v), wrap) | ||||||
|             pt.add_row([k, v]) |             pt.add_row([k, v]) | ||||||
|     print pt.get_string() |     print pt.get_string() | ||||||
|  |  | ||||||
|   | |||||||
| @@ -28,6 +28,9 @@ ALARM_STATES = ['ok', 'alarm', 'insufficient_data'] | |||||||
| ALARM_OPERATORS = ['lt', 'le', 'eq', 'ne', 'ge', 'gt'] | ALARM_OPERATORS = ['lt', 'le', 'eq', 'ne', 'ge', 'gt'] | ||||||
| ALARM_COMBINATION_OPERATORS = ['and', 'or'] | ALARM_COMBINATION_OPERATORS = ['and', 'or'] | ||||||
| STATISTICS = ['max', 'min', 'avg', 'sum', 'count'] | STATISTICS = ['max', 'min', 'avg', 'sum', 'count'] | ||||||
|  | OPERATORS_STRING = dict(gt='>', ge='>=', | ||||||
|  |                         lt='<', le="<=", | ||||||
|  |                         eq='==', ne='!=') | ||||||
|  |  | ||||||
|  |  | ||||||
| @utils.arg('-q', '--query', metavar='<QUERY>', | @utils.arg('-q', '--query', metavar='<QUERY>', | ||||||
| @@ -128,6 +131,28 @@ def do_meter_list(cc, args={}): | |||||||
|                      sortby=0) |                      sortby=0) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def alarm_rule_formatter(alarm): | ||||||
|  |     if alarm.type == 'threshold': | ||||||
|  |         return ('%(meter_name)s %(comparison_operator)s ' | ||||||
|  |                 '%(threshold)s during %(evaluation_periods)s x %(period)ss' % | ||||||
|  |                 { | ||||||
|  |                     'meter_name': alarm.rule['meter_name'], | ||||||
|  |                     'threshold': alarm.rule['threshold'], | ||||||
|  |                     'evaluation_periods': alarm.rule['evaluation_periods'], | ||||||
|  |                     'period': alarm.rule['period'], | ||||||
|  |                     'comparison_operator': OPERATORS_STRING.get( | ||||||
|  |                         alarm.rule['comparison_operator']) | ||||||
|  |                 }) | ||||||
|  |     elif alarm.type == 'combination': | ||||||
|  |         return ('combinated states (%(operator)s) of %(alarms)s' % { | ||||||
|  |             'operator': alarm.rule['operator'].upper(), | ||||||
|  |             'alarms': ", ".join(alarm.rule['alarm_ids'])}) | ||||||
|  |     else: | ||||||
|  |         # just dump all | ||||||
|  |         return "\n".join(["%s: %s" % (f, v) | ||||||
|  |                           for f, v in alarm.rule.iteritems()]) | ||||||
|  |  | ||||||
|  |  | ||||||
| @utils.arg('-q', '--query', metavar='<QUERY>', | @utils.arg('-q', '--query', metavar='<QUERY>', | ||||||
|            help='key[op]value; list.') |            help='key[op]value; list.') | ||||||
| def do_alarm_list(cc, args={}): | def do_alarm_list(cc, args={}): | ||||||
| @@ -135,20 +160,31 @@ def do_alarm_list(cc, args={}): | |||||||
|     alarms = cc.alarms.list(q=options.cli_to_array(args.query)) |     alarms = cc.alarms.list(q=options.cli_to_array(args.query)) | ||||||
|     # omit action initially to keep output width sane |     # omit action initially to keep output width sane | ||||||
|     # (can switch over to vertical formatting when available from CLIFF) |     # (can switch over to vertical formatting when available from CLIFF) | ||||||
|     field_labels = ['Name', 'Description', 'State', 'Enabled', 'Continuous', |     field_labels = ['Alarm ID', 'Name', 'State', 'Enabled', 'Continuous', | ||||||
|                     'Alarm ID', 'User ID', 'Project ID'] |                     'Alarm condition'] | ||||||
|     fields = ['name', 'description', 'state', 'enabled', 'repeat_actions', |     fields = ['alarm_id', 'name', 'state', 'enabled', 'repeat_actions', | ||||||
|               'alarm_id', 'user_id', 'project_id'] |               'rule'] | ||||||
|     utils.print_list(alarms, fields, field_labels, |     utils.print_list(alarms, fields, field_labels, | ||||||
|                      sortby=0) |                      formatters={'rule': alarm_rule_formatter}, sortby=0) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def alarm_query_formater(alarm): | ||||||
|  |     qs = [] | ||||||
|  |     for q in alarm.rule['query']: | ||||||
|  |         qs.append('%s %s %s' % ( | ||||||
|  |             q['field'], OPERATORS_STRING.get(q['op']), q['value'])) | ||||||
|  |     return r' AND\n'.join(qs) | ||||||
|  |  | ||||||
|  |  | ||||||
| def _display_alarm(alarm): | def _display_alarm(alarm): | ||||||
|     fields = ['name', 'description', 'type', 'rule', |     fields = ['name', 'description', 'type', | ||||||
|               'state', 'enabled', 'alarm_id', 'user_id', 'project_id', |               'state', 'enabled', 'alarm_id', 'user_id', 'project_id', | ||||||
|               'alarm_actions', 'ok_actions', 'insufficient_data_actions', |               'alarm_actions', 'ok_actions', 'insufficient_data_actions', | ||||||
|               'repeat_actions'] |               'repeat_actions'] | ||||||
|     data = dict([(f, getattr(alarm, f, '')) for f in fields]) |     data = dict([(f, getattr(alarm, f, '')) for f in fields]) | ||||||
|  |     data.update(alarm.rule) | ||||||
|  |     if alarm.type == 'threshold': | ||||||
|  |         data['query'] = alarm_query_formater(alarm) | ||||||
|     utils.print_dict(data, wrap=72) |     utils.print_dict(data, wrap=72) | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Mehdi Abaakouk
					Mehdi Abaakouk