提交 ed30ebf7 编写于 作者: N Nicolargo

Complete graph history feature #428

上级 41342c81
......@@ -343,6 +343,8 @@ class GlancesProcesses(object):
except KeyError:
# Key did not exist, create it
self.processcount[str(proc.status())] = 1
except psutil.NoSuchProcess:
pass
else:
self.processcount['total'] += 1
# Update thread number (global statistics)
......
......@@ -530,7 +530,8 @@ class GlancesCurses(object):
if self.history_tag and self.args.enable_history:
self.display_popup(
_("Generate graphs history in %s\nPlease wait...") % self.glances_history.get_output_folder())
self.glances_history.generate_graph(stats)
self.display_popup(
_("Generate graphs history in %s\nDone: %s graphs generated") % (self.glances_history.get_output_folder(), self.glances_history.generate_graph(stats)))
elif self.reset_history_tag and self.args.enable_history:
self.display_popup(_("Reset history"))
self.glances_history.reset(stats)
......@@ -580,13 +581,14 @@ class GlancesCurses(object):
"""
# Center the popup
sentence_list = message.split('\n')
if size_x is None:
size_x = len(message) + 4
size_x = len(max(sentence_list, key=len)) + 4
# Add space for the input field
if is_input:
size_x += input_size
if size_y is None:
size_y = message.count('\n') + 1 + 4
size_y = len(sentence_list) + 4
screen_x = self.screen.getmaxyx()[1]
screen_y = self.screen.getmaxyx()[0]
if size_x > screen_x or size_y > screen_y:
......
......@@ -76,55 +76,75 @@ class GlancesHistory(object):
else:
return ret
def get_graph_ylegend(self, item):
def get_graph_legend(self, item):
"""
Get the item's Y legend
Get the item's legend
"""
return item['name']
def get_graph_yunit(self, item, pre_label=''):
"""
Get the item's Y unit
"""
try:
ret = item['label_y']
unit = " (%s)" % item['y_unit']
except KeyError:
return ''
unit = ''
if pre_label == '':
label = ''
else:
return ' ' + ret
label = pre_label.split('_')[0]
return "%s%s" % (label, unit)
def generate_graph(self, stats):
"""
Generate graphs from plugins history
Return the number of output files generated by the function
"""
if not self.graph_enabled():
return False
return 0
index_all = 0
for p in stats.getAllPlugins():
h = stats.get_plugin(p).get_stats_history()
# Init graph
plt.clf()
fig = plt.gcf()
fig.set_size_inches(20, 10)
# Data
if h is None:
# History (h) not available for plugin (p)
continue
# Init graph
plt.clf()
index_graph = 0
handles = []
labels = []
for i in stats.get_plugin(p).get_items_history_list():
if i['name'] in h.keys():
# The key exist
# Add the curve in the current chart
# Add the curves in the current chart
logger.debug("Generate graph: %s %s" % (p, i['name']))
index_graph += 1
plt.title(p.capitalize())
plt.subplot(len(stats.get_plugin(p).get_items_history_list()), 1, index_graph)
plt.ylabel(i['name'] + self.get_graph_ylegend(i))
# Labels
handles.append(plt.Rectangle((0, 0), 1, 1, fc=self.get_graph_color(i), ec=self.get_graph_color(i), linewidth=2))
labels.append(self.get_graph_legend(i))
# Legend
plt.ylabel(self.get_graph_yunit(i, pre_label=''))
# Curves
plt.grid(True)
plt.plot_date(h['date'], h[i['name']],
fmt='', drawstyle='default', linestyle='-',
color=self.get_graph_color(i),
xdate=True, ydate=False)
if index_graph == 1:
# Title only on top of the first graph
plt.title(p.capitalize())
else:
# The key did not exist
# Find if anothers key ends with the key
# Ex: key='tx' => 'ethernet_tx'
stats_history_filtered = sorted([key for key in h.keys() if key.endswith(i['name'])])
logger.debug("Generate graphs: %s %s" % (p, stats_history_filtered))
# Add one curve per chart
stats_history_filtered = sorted(
[key for key in h.keys() if key.endswith('_' + i['name'])])
logger.debug("Generate graphs: %s %s" %
(p, stats_history_filtered))
if len(stats_history_filtered) > 0:
# Create 'n' graph
# Each graph iter through the stats
......@@ -132,56 +152,35 @@ class GlancesHistory(object):
index_item = 0
for k in stats_history_filtered:
index_item += 1
plt.title(p.capitalize())
plt.subplot(len(stats_history_filtered), 1, index_item)
plt.ylabel(k + self.get_graph_ylegend(i))
plt.subplot(
len(stats_history_filtered), 1, index_item)
plt.ylabel(self.get_graph_yunit(i, pre_label=k))
plt.grid(True)
plt.plot_date(h['date'], h[k],
fmt='', drawstyle='default', linestyle='-',
color=self.get_graph_color(i),
xdate=True, ydate=False)
if index_item == 1:
# Title only on top of the first graph
plt.title(p.capitalize() + ' ' + i['name'])
# Save the graph to output file
fig = plt.gcf()
fig.set_size_inches(20, 5 * index_item)
plt.xlabel('Date')
plt.savefig(os.path.join(self.output_folder, 'glances_%s_%s.png' % (p, i['name'])), dpi=72)
plt.savefig(
os.path.join(self.output_folder, 'glances_%s_%s.png' % (p, i['name'])), dpi=72)
index_all += 1
if index_graph > 0:
# Save the graph to output file
fig = plt.gcf()
fig.set_size_inches(20, 10)
plt.legend(handles, labels, loc=1, prop={'size': 9})
plt.xlabel('Date')
plt.savefig(os.path.join(self.output_folder, 'glances_%s.png' % (p)), dpi=72)
plt.savefig(
os.path.join(self.output_folder, 'glances_%s.png' % (p)), dpi=72)
index_all += 1
plt.close()
return True
def generate_graph_OLD(self, stats):
"""
Generate graphs from plugins history
"""
if not self.graph_enabled():
return False
for p in stats.getAllPlugins():
h = stats.get_plugin(p).get_stats_history()
# Generate graph (init)
plt.clf()
# Title and axis
plt.title(p.capitalize())
plt.grid(True)
if h is not None:
# History (h) available for plugin (p)
index = 1
for k, v in h.iteritems():
if k != 'date':
plt.subplot(len(h), 1, index)
index += 1
plt.xlabel('Date')
plt.ylabel(self.get_graph_ylegend(stats, p, k))
# Data
plt.plot_date(h['date'], h[k],
fmt='', drawstyle='default', linestyle='-',
color=self.get_graph_color(stats, p, k),
xdate=True, ydate=False)
# Save the graph to output file
plt.savefig(os.path.join(self.output_folder, 'glances_%s_%s.png' % (p, k)), dpi=72)
return True
return index_all
......@@ -36,10 +36,10 @@ snmp_oid = {'default': {'user': '1.3.6.1.4.1.2021.11.9.0',
# Define the history items list
# - 'name' define the stat identifier
# - 'color' define the graph color in #RGB format
# - 'label_y' define the Y label
# - 'y_unit' define the Y label
# All items in this list will be historised if the --enable-history tag is set
items_history_list = [{'name': 'user', 'color': '#00FF00', 'label_y': '(%)'},
{'name': 'system', 'color': '#FF0000', 'label_y': '(%)'}]
items_history_list = [{'name': 'user', 'color': '#00FF00', 'y_unit': '%'},
{'name': 'system', 'color': '#FF0000', 'y_unit': '%'}]
class Plugin(GlancesPlugin):
......
......@@ -28,8 +28,8 @@ import psutil
# Define the history items list
# All items in this list will be historised if the --enable-history tag is set
# 'color' define the graph color in #RGB format
items_history_list = [{'name': 'read_bytes', 'color': '#00FF00', 'label_y': '(B/s)'},
{'name': 'write_bytes', 'color': '#FF0000', 'label_y': '(B/s)'}]
items_history_list = [{'name': 'read_bytes', 'color': '#00FF00', 'y_unit': 'B/s'},
{'name': 'write_bytes', 'color': '#FF0000', 'y_unit': 'B/s'}]
class Plugin(GlancesPlugin):
......
......@@ -48,7 +48,7 @@ snmp_oid = {'default': {'total': '1.3.6.1.4.1.2021.4.5.0',
# Define the history items list
# All items in this list will be historised if the --enable-history tag is set
# 'color' define the graph color in #RGB format
items_history_list = [{'name': 'percent', 'color': '#00FF00'}]
items_history_list = [{'name': 'percent', 'color': '#00FF00', 'y_unit': '%'}]
class Plugin(GlancesPlugin):
......
......@@ -36,7 +36,7 @@ snmp_oid = {'default': {'total': '1.3.6.1.4.1.2021.4.3.0',
# Define the history items list
# All items in this list will be historised if the --enable-history tag is set
# 'color' define the graph color in #RGB format
items_history_list = [{'name': 'percent', 'color': '#00FF00'}]
items_history_list = [{'name': 'percent', 'color': '#00FF00', 'y_unit': '%'}]
class Plugin(GlancesPlugin):
......
......@@ -36,8 +36,8 @@ snmp_oid = {'default': {'interface_name': '1.3.6.1.2.1.2.2.1.2',
# Define the history items list
# All items in this list will be historised if the --enable-history tag is set
# 'color' define the graph color in #RGB format
items_history_list = [{'name': 'rx', 'color': '#00FF00', 'label_y': '(bit/s)'},
{'name': 'tx', 'color': '#FF0000', 'label_y': '(bit/s)'}]
items_history_list = [{'name': 'rx', 'color': '#00FF00', 'y_unit': 'bit/s'},
{'name': 'tx', 'color': '#FF0000', 'y_unit': 'bit/s'}]
class Plugin(GlancesPlugin):
......
......@@ -23,6 +23,9 @@
from glances.core.glances_globals import glances_processes
from glances.plugins.glances_plugin import GlancesPlugin
# Note: history items list is not compliant with process count
# if a filter is applyed, the graph will show the filtered processes count
class Plugin(GlancesPlugin):
......
......@@ -27,7 +27,7 @@ except ImportError:
pass
# Import Glances lib
from glances.core.glances_globals import is_py3, logger
from glances.core.glances_globals import is_py3
from glances.plugins.glances_batpercent import Plugin as BatPercentPlugin
from glances.plugins.glances_hddtemp import Plugin as HddTempPlugin
from glances.plugins.glances_plugin import GlancesPlugin
......@@ -49,10 +49,12 @@ class Plugin(GlancesPlugin):
# Init the sensor class
self.glancesgrabsensors = GlancesGrabSensors()
# Instance for the HDDTemp Plugin in order to display the hard disks temperatures
# Instance for the HDDTemp Plugin in order to display the hard disks
# temperatures
self.hddtemp_plugin = HddTempPlugin(args=args)
# Instance for the BatPercent in order to display the batteries capacities
# Instance for the BatPercent in order to display the batteries
# capacities
self.batpercent_plugin = BatPercentPlugin(args=args)
# We want to display the stat in the curse interface
......@@ -73,13 +75,13 @@ class Plugin(GlancesPlugin):
if self.get_input() == 'local':
# Update stats using the dedicated lib
try:
self.stats = self.__set_type(self.glancesgrabsensors.get(),
self.stats = self.__set_type(self.glancesgrabsensors.get(),
'temperature_core')
except:
pass
# Update HDDtemp stats
try:
hddtemp = self.__set_type(self.hddtemp_plugin.update(),
hddtemp = self.__set_type(self.hddtemp_plugin.update(),
'temperature_hdd')
except:
pass
......@@ -88,7 +90,7 @@ class Plugin(GlancesPlugin):
self.stats.extend(hddtemp)
# Update batteries stats
try:
batpercent = self.__set_type(self.batpercent_plugin.update(),
batpercent = self.__set_type(self.batpercent_plugin.update(),
'battery')
except:
pass
......@@ -97,7 +99,8 @@ class Plugin(GlancesPlugin):
self.stats.extend(batpercent)
elif self.get_input() == 'snmp':
# Update stats using SNMP
# No standard: http://www.net-snmp.org/wiki/index.php/Net-SNMP_and_lm-sensors_on_Ubuntu_10.04
# No standard:
# http://www.net-snmp.org/wiki/index.php/Net-SNMP_and_lm-sensors_on_Ubuntu_10.04
pass
return self.stats
......@@ -147,11 +150,13 @@ class Plugin(GlancesPlugin):
msg = '{0:>5}'.format(item['value'])
if item['type'] == 'battery':
try:
ret.append(self.curse_add_line(msg, self.get_alert(100 - item['value'], header=item['type'])))
ret.append(self.curse_add_line(
msg, self.get_alert(100 - item['value'], header=item['type'])))
except TypeError:
pass
else:
ret.append(self.curse_add_line(msg, self.get_alert(item['value'], header=item['type'])))
ret.append(
self.curse_add_line(msg, self.get_alert(item['value'], header=item['type'])))
return ret
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册