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:
Mehdi Abaakouk
2013-09-24 11:09:05 +02:00
parent 2610d6c144
commit ce01f56465
2 changed files with 46 additions and 8 deletions

View File

@@ -63,17 +63,19 @@ def print_dict(d, dict_property="Property", wrap=0):
# convert dict to str to check length
if isinstance(v, dict):
v = str(v)
if wrap > 0:
v = textwrap.fill(str(v), wrap)
# if value has a newline, add in multiple rows
# e.g. fault with stacktrace
if v and isinstance(v, basestring) and r'\n' in v:
lines = v.strip().split(r'\n')
col1 = k
for line in lines:
if wrap > 0:
line = textwrap.fill(str(line), wrap)
pt.add_row([col1, line])
col1 = ''
else:
if wrap > 0:
v = textwrap.fill(str(v), wrap)
pt.add_row([k, v])
print pt.get_string()

View File

@@ -28,6 +28,9 @@ ALARM_STATES = ['ok', 'alarm', 'insufficient_data']
ALARM_OPERATORS = ['lt', 'le', 'eq', 'ne', 'ge', 'gt']
ALARM_COMBINATION_OPERATORS = ['and', 'or']
STATISTICS = ['max', 'min', 'avg', 'sum', 'count']
OPERATORS_STRING = dict(gt='>', ge='>=',
lt='<', le="<=",
eq='==', ne='!=')
@utils.arg('-q', '--query', metavar='<QUERY>',
@@ -128,6 +131,28 @@ def do_meter_list(cc, args={}):
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>',
help='key[op]value; list.')
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))
# omit action initially to keep output width sane
# (can switch over to vertical formatting when available from CLIFF)
field_labels = ['Name', 'Description', 'State', 'Enabled', 'Continuous',
'Alarm ID', 'User ID', 'Project ID']
fields = ['name', 'description', 'state', 'enabled', 'repeat_actions',
'alarm_id', 'user_id', 'project_id']
field_labels = ['Alarm ID', 'Name', 'State', 'Enabled', 'Continuous',
'Alarm condition']
fields = ['alarm_id', 'name', 'state', 'enabled', 'repeat_actions',
'rule']
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):
fields = ['name', 'description', 'type', 'rule',
fields = ['name', 'description', 'type',
'state', 'enabled', 'alarm_id', 'user_id', 'project_id',
'alarm_actions', 'ok_actions', 'insufficient_data_actions',
'repeat_actions']
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)