Add IPMI metrics to node detail page
Add four new IPMI metrics (Current, Temperature, Fan Speed and Voltage) to the node detail page. Change-Id: I0ea141f146c5d946919af2a70cff51bf2a8dec67
This commit is contained in:
parent
ef98fbb619
commit
10ec89b16e
@ -306,10 +306,11 @@ class DetailOverviewTab(tabs.Tab):
|
||||
else:
|
||||
context['role'] = resource.role
|
||||
context['stack'] = resource.stack
|
||||
|
||||
if node.instance_uuid:
|
||||
if api_base.is_service_enabled(self.request, 'metering'):
|
||||
# Meter configuration in the following format:
|
||||
# (meter label, url part, barchart (True/False))
|
||||
# (meter label, url part, y_max)
|
||||
context['meter_conf'] = (
|
||||
(_('System Load'),
|
||||
metering_utils.url_part('hardware.cpu.load.1min', False),
|
||||
@ -322,11 +323,24 @@ class DetailOverviewTab(tabs.Tab):
|
||||
metering_utils.url_part('hardware.memory.swap.util',
|
||||
True),
|
||||
'100'),
|
||||
(_('Disk I/O '),
|
||||
(_('Current'),
|
||||
metering_utils.url_part('hardware.ipmi.current', False),
|
||||
None),
|
||||
(_('Network IO'),
|
||||
metering_utils.url_part('network-io', False),
|
||||
None),
|
||||
(_('Disk IO'),
|
||||
metering_utils.url_part('disk-io', False),
|
||||
None),
|
||||
(_('Network I/O '),
|
||||
metering_utils.url_part('network-io', False),
|
||||
(_('Temperature'),
|
||||
metering_utils.url_part('hardware.ipmi.temperature',
|
||||
False),
|
||||
None),
|
||||
(_('Fan Speed'),
|
||||
metering_utils.url_part('hardware.ipmi.fan', False),
|
||||
None),
|
||||
(_('Voltage'),
|
||||
metering_utils.url_part('hardware.ipmi.voltage', False),
|
||||
None),
|
||||
)
|
||||
return context
|
||||
|
@ -404,7 +404,7 @@ class NodesTests(test.BaseAdminViewTests):
|
||||
'server_list.return_value': ([instance], None),
|
||||
}),
|
||||
patch('tuskar_ui.utils.metering.query_data',
|
||||
return_value=([], 'unit')),
|
||||
return_value=[]),
|
||||
):
|
||||
url = urlresolvers.reverse(PERFORMANCE_VIEW, args=(node.uuid,))
|
||||
url += '?meter=cpu&date_options=7'
|
||||
|
@ -156,8 +156,8 @@ class PerformanceView(base.TemplateView):
|
||||
instance_uuid = None
|
||||
|
||||
json_output = metering_utils.get_nodes_stats(
|
||||
request, instance_uuid, meter, date_options=date_options,
|
||||
date_from=date_from, date_to=date_to,
|
||||
request, node_uuid, instance_uuid, meter,
|
||||
date_options=date_options, date_from=date_from, date_to=date_to,
|
||||
stats_attr=stats_attr, barchart=barchart)
|
||||
|
||||
return django.http.HttpResponse(
|
||||
|
@ -88,13 +88,6 @@ def query_data(request,
|
||||
|
||||
# TODO(lsmola) replace this by logic implemented in I1 in bugs
|
||||
# 1226479 and 1226482, this is just a quick fix for RC1
|
||||
try:
|
||||
meter_list = [m for m in ceilometer.meter_list(request)
|
||||
if m.name == meter]
|
||||
unit = meter_list[0].unit
|
||||
except Exception:
|
||||
unit = ""
|
||||
|
||||
ceilometer_usage = ceilometer.CeilometerUsage(request)
|
||||
try:
|
||||
if group_by:
|
||||
@ -109,7 +102,7 @@ def query_data(request,
|
||||
resources = []
|
||||
exceptions.handle(request,
|
||||
_('Unable to retrieve statistics.'))
|
||||
return resources, unit
|
||||
return resources
|
||||
|
||||
|
||||
def url_part(meter_name, barchart):
|
||||
@ -168,28 +161,51 @@ def create_json_output(series, barchart, unit, date_from, date_to):
|
||||
return json_output
|
||||
|
||||
|
||||
def get_nodes_stats(request, uuid, meter, date_options=None, date_from=None,
|
||||
date_to=None, stats_attr=None, barchart=None,
|
||||
group_by=None):
|
||||
|
||||
unit = ''
|
||||
def get_nodes_stats(request, node_uuid, instance_uuid, meter,
|
||||
date_options=None, date_from=None, date_to=None,
|
||||
stats_attr=None, barchart=None, group_by=None):
|
||||
series = []
|
||||
|
||||
if uuid:
|
||||
if group_by == "image_id":
|
||||
query = {}
|
||||
image_query = [{"field": "metadata.%s" % group_by,
|
||||
"op": "eq",
|
||||
"value": uuid}]
|
||||
query[uuid] = image_query
|
||||
try:
|
||||
meter_list = [m for m in ceilometer.meter_list(request)
|
||||
if m.name == meter]
|
||||
unit = meter_list[0].unit
|
||||
except Exception:
|
||||
meter_list = []
|
||||
unit = ''
|
||||
|
||||
if instance_uuid:
|
||||
if 'ipmi' in meter:
|
||||
# For IPMI metrics, a resource ID is made of node UUID concatenated
|
||||
# with the metric description. E.g:
|
||||
# 1dcf1896-f581-4027-9efa-973eef3380d2-fan_2a_tach_(0x42)
|
||||
resource_ids = [m.resource_id for m in meter_list
|
||||
if m.resource_id.startswith(node_uuid)]
|
||||
queries = [
|
||||
[{'field': 'resource_id',
|
||||
'op': 'eq',
|
||||
'value': resource_id}]
|
||||
for resource_id in resource_ids
|
||||
]
|
||||
else:
|
||||
query = [{'field': 'resource_id',
|
||||
'op': 'eq',
|
||||
'value': uuid}]
|
||||
# For SNMP metrics, a resource ID matches exactly the UUID of the
|
||||
# associated instance
|
||||
if group_by == "image_id":
|
||||
query = {}
|
||||
image_query = [{"field": "metadata.%s" % group_by,
|
||||
"op": "eq",
|
||||
"value": instance_uuid}]
|
||||
query[instance_uuid] = image_query
|
||||
else:
|
||||
query = [{'field': 'resource_id',
|
||||
'op': 'eq',
|
||||
'value': instance_uuid}]
|
||||
queries = [query]
|
||||
else:
|
||||
# query will be aggregated across all resources
|
||||
group_by = "all"
|
||||
query = {'all': []}
|
||||
queries = [query]
|
||||
|
||||
# Disk and Network I/O: data from 2 meters in one chart
|
||||
if meter == 'disk-io':
|
||||
@ -212,16 +228,19 @@ def get_nodes_stats(request, uuid, meter, date_options=None, date_from=None,
|
||||
|
||||
for meter_id, meter_name in meters:
|
||||
label = unicode(LABELS.get(meter_id, meter_name))
|
||||
resources, unit = query_data(
|
||||
request=request,
|
||||
date_from=date_from,
|
||||
date_to=date_to,
|
||||
group_by=group_by,
|
||||
meter=meter_id,
|
||||
query=query)
|
||||
s = metering.series_for_meter(request, resources, group_by, meter_id,
|
||||
meter_name, stats_attr, unit, label)
|
||||
series += s
|
||||
|
||||
for query in queries:
|
||||
resources = query_data(
|
||||
request=request,
|
||||
date_from=date_from,
|
||||
date_to=date_to,
|
||||
group_by=group_by,
|
||||
meter=meter_id,
|
||||
query=query)
|
||||
s = metering.series_for_meter(request, resources, group_by,
|
||||
meter_id, meter_name, stats_attr,
|
||||
unit, label)
|
||||
series += s
|
||||
|
||||
series = metering.normalize_series_by_unit(series)
|
||||
|
||||
|
@ -95,7 +95,7 @@ class MeteringTests(helpers.TestCase):
|
||||
):
|
||||
ret = metering.query_data(request, from_date, to_date,
|
||||
'all', 'foo.bar')
|
||||
self.assertEqual(ret, ('plonk', u'µD'))
|
||||
self.assertEqual(ret, 'plonk')
|
||||
|
||||
def test_url_part(self):
|
||||
ret = metering.url_part('foo_bar_baz', True)
|
||||
@ -192,7 +192,7 @@ class MeteringTests(helpers.TestCase):
|
||||
return_value='',
|
||||
) as create_json_output, mock.patch(
|
||||
'tuskar_ui.utils.metering.query_data',
|
||||
return_value=([], u'µD'),
|
||||
return_value=[],
|
||||
), mock.patch(
|
||||
'openstack_dashboard.utils.metering.series_for_meter',
|
||||
return_value=[],
|
||||
@ -200,8 +200,8 @@ class MeteringTests(helpers.TestCase):
|
||||
'openstack_dashboard.utils.metering.calc_date_args',
|
||||
return_value=('from date', 'to date'),
|
||||
):
|
||||
ret = metering.get_nodes_stats(request, 'abc', 'foo.bar')
|
||||
ret = metering.get_nodes_stats(request, 'abc', 'def', 'foo.bar')
|
||||
self.assertEqual(ret, '')
|
||||
self.assertEqual(create_json_output.call_args_list, [
|
||||
mock.call([], None, u'µD', 'from date', 'to date')
|
||||
mock.call([], None, '', 'from date', 'to date')
|
||||
])
|
||||
|
Loading…
x
Reference in New Issue
Block a user