Implementation issue #878 ok for the curses interface. To be done in the WebUI and code should be optimized

pull/979/head
nicolargo 2016-09-18 22:31:45 +02:00
parent 874f6ceceb
commit 99268f3b4f
4 changed files with 73 additions and 17 deletions

View File

@ -194,19 +194,19 @@ class _GlancesCurses(object):
else: else:
curses.init_pair(10, curses.COLOR_WHITE, -1) curses.init_pair(10, curses.COLOR_WHITE, -1)
self.ifWARNING_color2 = curses.color_pair(9) | A_BOLD self.ifWARNING_color2 = curses.color_pair(9)
self.ifCRITICAL_color2 = curses.color_pair(6) | A_BOLD self.ifCRITICAL_color2 = curses.color_pair(6)
self.filter_color = curses.color_pair(10) | A_BOLD self.filter_color = curses.color_pair(10) | A_BOLD
self.no_color = curses.color_pair(1) self.no_color = curses.color_pair(1)
self.default_color = curses.color_pair(3) | A_BOLD self.default_color = curses.color_pair(3)
self.nice_color = curses.color_pair(9) | A_BOLD self.nice_color = curses.color_pair(9)
self.cpu_time_color = curses.color_pair(9) | A_BOLD self.cpu_time_color = curses.color_pair(9)
self.ifCAREFUL_color = curses.color_pair(4) | A_BOLD self.ifCAREFUL_color = curses.color_pair(4)
self.ifWARNING_color = curses.color_pair(5) | A_BOLD self.ifWARNING_color = curses.color_pair(5)
self.ifCRITICAL_color = curses.color_pair(2) | A_BOLD self.ifCRITICAL_color = curses.color_pair(2)
self.default_color2 = curses.color_pair(7) | A_BOLD self.default_color2 = curses.color_pair(7)
self.ifCAREFUL_color2 = curses.color_pair(8) | A_BOLD self.ifCAREFUL_color2 = curses.color_pair(8)
else: else:
# The screen is NOT compatible with a colored design # The screen is NOT compatible with a colored design
@ -231,6 +231,7 @@ class _GlancesCurses(object):
'BOLD': A_BOLD, 'BOLD': A_BOLD,
'SORT': A_BOLD, 'SORT': A_BOLD,
'OK': self.default_color2, 'OK': self.default_color2,
'MAX': self.default_color2 | curses.A_BOLD,
'FILTER': self.filter_color, 'FILTER': self.filter_color,
'TITLE': self.title_color, 'TITLE': self.title_color,
'PROCESS': self.default_color2, 'PROCESS': self.default_color2,

View File

@ -437,6 +437,7 @@ class GlancesPlugin(object):
minimum=0, minimum=0,
maximum=100, maximum=100,
highlight_zero=True, highlight_zero=True,
is_max=False,
header="", header="",
log=False): log=False):
"""Return the alert status relative to a current value. """Return the alert status relative to a current value.
@ -476,7 +477,8 @@ class GlancesPlugin(object):
stat_name = self.plugin_name + '_' + header stat_name = self.plugin_name + '_' + header
# Manage limits # Manage limits
ret = 'OK' # If is_max is set then display the value in MAX
ret = 'MAX' if is_max else 'OK'
try: try:
if value > self.__get_limit('critical', stat_name=stat_name): if value > self.__get_limit('critical', stat_name=stat_name):
ret = 'CRITICAL' ret = 'CRITICAL'
@ -528,7 +530,11 @@ class GlancesPlugin(object):
def get_alert_log(self, current=0, minimum=0, maximum=100, header=""): def get_alert_log(self, current=0, minimum=0, maximum=100, header=""):
"""Get the alert log.""" """Get the alert log."""
return self.get_alert(current, minimum, maximum, header, log=True) return self.get_alert(current=current,
minimum=minimum,
maximum=maximum,
header=header,
log=True)
def __get_limit(self, criticity, stat_name=""): def __get_limit(self, criticity, stat_name=""):
"""Return the limit value for the alert.""" """Return the limit value for the alert."""

View File

@ -79,6 +79,9 @@ class Plugin(GlancesPlugin):
except Exception: except Exception:
self.nb_log_core = 0 self.nb_log_core = 0
# Get the max values (dict)
max_values = glances_processes.max_values()
# Note: 'glances_processes' is already init in the processes.py script # Note: 'glances_processes' is already init in the processes.py script
def get_key(self): def get_key(self):
@ -102,6 +105,10 @@ class Plugin(GlancesPlugin):
self.stats = glances_processes.gettree() self.stats = glances_processes.gettree()
else: else:
self.stats = glances_processes.getlist() self.stats = glances_processes.getlist()
# Get the max values (dict)
self.max_values = glances_processes.max_values()
elif self.input_method == 'snmp': elif self.input_method == 'snmp':
# No SNMP grab for processes # No SNMP grab for processes
pass pass
@ -190,7 +197,10 @@ class Plugin(GlancesPlugin):
return child_data return child_data
def get_process_curses_data(self, p, first, args): def get_process_curses_data(self, p, first, args):
"""Get curses data to display for a process.""" """Get curses data to display for a process.
- p is the process to display
- first is a tag=True if the process is the first on the list
"""
ret = [self.curse_new_line()] ret = [self.curse_new_line()]
# CPU # CPU
if 'cpu_percent' in p and p['cpu_percent'] is not None and p['cpu_percent'] != '': if 'cpu_percent' in p and p['cpu_percent'] is not None and p['cpu_percent'] != '':
@ -198,16 +208,22 @@ class Plugin(GlancesPlugin):
msg = '{:>6.1f}'.format(p['cpu_percent'] / float(self.nb_log_core)) msg = '{:>6.1f}'.format(p['cpu_percent'] / float(self.nb_log_core))
else: else:
msg = '{:>6.1f}'.format(p['cpu_percent']) msg = '{:>6.1f}'.format(p['cpu_percent'])
ret.append(self.curse_add_line(msg, alert = self.get_alert(p['cpu_percent'],
self.get_alert(p['cpu_percent'], highlight_zero=False, header="cpu"))) highlight_zero=False,
is_max=(p['cpu_percent']==self.max_values['cpu_percent']),
header="cpu")
ret.append(self.curse_add_line(msg, alert))
else: else:
msg = '{:>6}'.format('?') msg = '{:>6}'.format('?')
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
# MEM # MEM
if 'memory_percent' in p and p['memory_percent'] is not None and p['memory_percent'] != '': if 'memory_percent' in p and p['memory_percent'] is not None and p['memory_percent'] != '':
msg = '{:>6.1f}'.format(p['memory_percent']) msg = '{:>6.1f}'.format(p['memory_percent'])
ret.append(self.curse_add_line(msg, alert = self.get_alert(p['memory_percent'],
self.get_alert(p['memory_percent'], highlight_zero=False, header="mem"))) highlight_zero=False,
is_max=(p['memory_percent']==self.max_values['memory_percent']),
header="mem")
ret.append(self.curse_add_line(msg, alert))
else: else:
msg = '{:>6}'.format('?') msg = '{:>6}'.format('?')
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))

View File

@ -88,6 +88,13 @@ class GlancesProcesses(object):
# Whether or not to hide kernel threads # Whether or not to hide kernel threads
self.no_kernel_threads = False self.no_kernel_threads = False
# Store maximums values in a dict
# Used in the UI to highlight the maximum value
self._max_values_list = ('cpu_percent', 'memory_percent')
# { 'cpu_percent': 0.0, 'memory_percent': 0.0 }
self._max_values = {}
self.reset_max_values()
def enable(self): def enable(self):
"""Enable process stats.""" """Enable process stats."""
self.disable_tag = False self.disable_tag = False
@ -161,6 +168,24 @@ class GlancesProcesses(object):
return True return True
def max_values(self):
"""Return the max values dict."""
return self._max_values
def get_max_values(self, key):
"""Get the maximum values of the given stat (key)."""
return self._max_values[key]
def set_max_values(self, key, value):
"""Set the maximum value for a specific stat (key)."""
self._max_values[key] = value
def reset_max_values(self):
"""Reset the maximum values dict."""
self._max_values = {}
for k in self._max_values_list:
self._max_values[k] = 0.0
def __get_mandatory_stats(self, proc, procstat): def __get_mandatory_stats(self, proc, procstat):
""" """
Get mandatory_stats: need for the sorting/filter step. Get mandatory_stats: need for the sorting/filter step.
@ -182,6 +207,11 @@ class GlancesProcesses(object):
# cpu_percent or memory_percent stats # cpu_percent or memory_percent stats
return None return None
# Compute the maximum value for cpu_percent and memory_percent
for k in self._max_values_list:
if procstat[k] > self.get_max_values(k):
self.set_max_values(k, procstat[k])
# Process command line (cached with internal cache) # Process command line (cached with internal cache)
try: try:
self.cmdline_cache[procstat['pid']] self.cmdline_cache[procstat['pid']]
@ -387,6 +417,9 @@ class GlancesProcesses(object):
# Get the time since last update # Get the time since last update
time_since_update = getTimeSinceLastUpdate('process_disk') time_since_update = getTimeSinceLastUpdate('process_disk')
# Reset the max dict
self.reset_max_values()
# Build an internal dict with only mandatories stats (sort keys) # Build an internal dict with only mandatories stats (sort keys)
processdict = {} processdict = {}
excluded_processes = set() excluded_processes = set()