From 99268f3b4fcf4c425883090c3e04b84eb0352533 Mon Sep 17 00:00:00 2001 From: nicolargo Date: Sun, 18 Sep 2016 22:31:45 +0200 Subject: [PATCH] Implementation issue #878 ok for the curses interface. To be done in the WebUI and code should be optimized --- glances/outputs/glances_curses.py | 21 ++++++++-------- glances/plugins/glances_plugin.py | 10 ++++++-- glances/plugins/glances_processlist.py | 26 ++++++++++++++++---- glances/processes.py | 33 ++++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 17 deletions(-) diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py index 1cf6f273..1273cc33 100644 --- a/glances/outputs/glances_curses.py +++ b/glances/outputs/glances_curses.py @@ -194,19 +194,19 @@ class _GlancesCurses(object): else: curses.init_pair(10, curses.COLOR_WHITE, -1) - self.ifWARNING_color2 = curses.color_pair(9) | A_BOLD - self.ifCRITICAL_color2 = curses.color_pair(6) | A_BOLD + self.ifWARNING_color2 = curses.color_pair(9) + self.ifCRITICAL_color2 = curses.color_pair(6) self.filter_color = curses.color_pair(10) | A_BOLD self.no_color = curses.color_pair(1) - self.default_color = curses.color_pair(3) | A_BOLD - self.nice_color = curses.color_pair(9) | A_BOLD - self.cpu_time_color = curses.color_pair(9) | A_BOLD - self.ifCAREFUL_color = curses.color_pair(4) | A_BOLD - self.ifWARNING_color = curses.color_pair(5) | A_BOLD - self.ifCRITICAL_color = curses.color_pair(2) | A_BOLD - self.default_color2 = curses.color_pair(7) | A_BOLD - self.ifCAREFUL_color2 = curses.color_pair(8) | A_BOLD + self.default_color = curses.color_pair(3) + self.nice_color = curses.color_pair(9) + self.cpu_time_color = curses.color_pair(9) + self.ifCAREFUL_color = curses.color_pair(4) + self.ifWARNING_color = curses.color_pair(5) + self.ifCRITICAL_color = curses.color_pair(2) + self.default_color2 = curses.color_pair(7) + self.ifCAREFUL_color2 = curses.color_pair(8) else: # The screen is NOT compatible with a colored design @@ -231,6 +231,7 @@ class _GlancesCurses(object): 'BOLD': A_BOLD, 'SORT': A_BOLD, 'OK': self.default_color2, + 'MAX': self.default_color2 | curses.A_BOLD, 'FILTER': self.filter_color, 'TITLE': self.title_color, 'PROCESS': self.default_color2, diff --git a/glances/plugins/glances_plugin.py b/glances/plugins/glances_plugin.py index 6c831d56..87b6e99f 100644 --- a/glances/plugins/glances_plugin.py +++ b/glances/plugins/glances_plugin.py @@ -437,6 +437,7 @@ class GlancesPlugin(object): minimum=0, maximum=100, highlight_zero=True, + is_max=False, header="", log=False): """Return the alert status relative to a current value. @@ -476,7 +477,8 @@ class GlancesPlugin(object): stat_name = self.plugin_name + '_' + header # Manage limits - ret = 'OK' + # If is_max is set then display the value in MAX + ret = 'MAX' if is_max else 'OK' try: if value > self.__get_limit('critical', stat_name=stat_name): ret = 'CRITICAL' @@ -528,7 +530,11 @@ class GlancesPlugin(object): def get_alert_log(self, current=0, minimum=0, maximum=100, header=""): """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=""): """Return the limit value for the alert.""" diff --git a/glances/plugins/glances_processlist.py b/glances/plugins/glances_processlist.py index ae090c30..9de69484 100644 --- a/glances/plugins/glances_processlist.py +++ b/glances/plugins/glances_processlist.py @@ -79,6 +79,9 @@ class Plugin(GlancesPlugin): except Exception: 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 def get_key(self): @@ -102,6 +105,10 @@ class Plugin(GlancesPlugin): self.stats = glances_processes.gettree() else: self.stats = glances_processes.getlist() + + # Get the max values (dict) + self.max_values = glances_processes.max_values() + elif self.input_method == 'snmp': # No SNMP grab for processes pass @@ -190,7 +197,10 @@ class Plugin(GlancesPlugin): return child_data 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()] # CPU 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)) else: msg = '{:>6.1f}'.format(p['cpu_percent']) - ret.append(self.curse_add_line(msg, - self.get_alert(p['cpu_percent'], highlight_zero=False, header="cpu"))) + alert = self.get_alert(p['cpu_percent'], + highlight_zero=False, + is_max=(p['cpu_percent']==self.max_values['cpu_percent']), + header="cpu") + ret.append(self.curse_add_line(msg, alert)) else: msg = '{:>6}'.format('?') ret.append(self.curse_add_line(msg)) # MEM if 'memory_percent' in p and p['memory_percent'] is not None and p['memory_percent'] != '': msg = '{:>6.1f}'.format(p['memory_percent']) - ret.append(self.curse_add_line(msg, - self.get_alert(p['memory_percent'], highlight_zero=False, header="mem"))) + alert = self.get_alert(p['memory_percent'], + highlight_zero=False, + is_max=(p['memory_percent']==self.max_values['memory_percent']), + header="mem") + ret.append(self.curse_add_line(msg, alert)) else: msg = '{:>6}'.format('?') ret.append(self.curse_add_line(msg)) diff --git a/glances/processes.py b/glances/processes.py index 250b4153..d3485fd1 100644 --- a/glances/processes.py +++ b/glances/processes.py @@ -88,6 +88,13 @@ class GlancesProcesses(object): # Whether or not to hide kernel threads 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): """Enable process stats.""" self.disable_tag = False @@ -161,6 +168,24 @@ class GlancesProcesses(object): 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): """ Get mandatory_stats: need for the sorting/filter step. @@ -182,6 +207,11 @@ class GlancesProcesses(object): # cpu_percent or memory_percent stats 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) try: self.cmdline_cache[procstat['pid']] @@ -387,6 +417,9 @@ class GlancesProcesses(object): # Get the time since last update time_since_update = getTimeSinceLastUpdate('process_disk') + # Reset the max dict + self.reset_max_values() + # Build an internal dict with only mandatories stats (sort keys) processdict = {} excluded_processes = set()