diff options
author | nicolargo <nicolas@nicolargo.com> | 2022-12-29 12:05:01 +0100 |
---|---|---|
committer | nicolargo <nicolas@nicolargo.com> | 2022-12-29 12:05:01 +0100 |
commit | ab68b362a11a256560646050a06568e875ea54be (patch) | |
tree | b38036d13ea267ca05a6ad899aa8405abf41b733 | |
parent | d6bdb8dd8e5be7495f842a480ee88aaedf04078e (diff) |
CPU and MEM ok
-rw-r--r-- | glances/outputs/glances_curses.py | 3 | ||||
-rw-r--r-- | glances/plugins/glances_processlist.py | 31 | ||||
-rw-r--r-- | glances/processes.py | 46 |
3 files changed, 60 insertions, 20 deletions
diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py index a81192c6..debdd8b8 100644 --- a/glances/outputs/glances_curses.py +++ b/glances/outputs/glances_curses.py @@ -268,6 +268,7 @@ class _GlancesCurses(object): self.ifCAREFUL_color2 = curses.color_pair(8) | A_BOLD self.ifWARNING_color2 = curses.color_pair(5) | A_BOLD self.ifCRITICAL_color2 = curses.color_pair(6) | A_BOLD + self.ifINFO_color = curses.color_pair(8) self.filter_color = A_BOLD self.selected_color = A_BOLD @@ -301,6 +302,7 @@ class _GlancesCurses(object): self.ifCAREFUL_color2 = curses.A_UNDERLINE self.ifWARNING_color2 = A_BOLD self.ifCRITICAL_color2 = curses.A_REVERSE + self.ifINFO_color = A_BOLD self.filter_color = A_BOLD self.selected_color = A_BOLD @@ -328,6 +330,7 @@ class _GlancesCurses(object): 'CRITICAL_LOG': self.ifCRITICAL_color, 'PASSWORD': curses.A_PROTECT, 'SELECTED': self.selected_color, + 'INFO': self.ifINFO_color } def set_cursor(self, value): diff --git a/glances/plugins/glances_processlist.py b/glances/plugins/glances_processlist.py index 66a62f32..c715b98c 100644 --- a/glances/plugins/glances_processlist.py +++ b/glances/plugins/glances_processlist.py @@ -20,6 +20,7 @@ from glances.outputs.glances_unicode import unicode_message from glances.plugins.glances_core import Plugin as CorePlugin from glances.plugins.glances_plugin import GlancesPlugin from glances.programs import processes_to_programs +from glances.outputs.glances_bars import Bar def seconds_to_hms(input_seconds): @@ -502,7 +503,10 @@ class Plugin(GlancesPlugin): 'key': 'pid', 'time_since_update': 2.1997854709625244, 'cmdline': ['/snap/firefox/2154/usr/lib/firefox/firefox', '-contentproc', '-childID', '...'], - 'username': 'nicolargo'} + 'username': 'nicolargo', + 'cpu_min': 0.0, + 'cpu_max': 7.0, + 'cpu_mean': 3.2} """ if self.args.programs: self.__msg_curse_extended_process_program(ret, p) @@ -519,21 +523,32 @@ class Plugin(GlancesPlugin): def __msg_curse_extended_process_thread(self, ret, p): # Title - msg = "Pinned thread {} ('e' to unpin)".format(p['name']) - ret.append(self.curse_add_line(msg, "TITLE")) + ret.append(self.curse_add_line("Pinned thread ", "TITLE")) + ret.append(self.curse_add_line(p['name'], "UNDERLINE")) + ret.append(self.curse_add_line(" ('e' to unpin)")) # First line is CPU affinity + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(' CPU affinity ')) if 'cpu_affinity' in p and p['cpu_affinity'] is not None: - ret.append(self.curse_new_line()) - msg = 'CPU affinity: ' + str(len(p['cpu_affinity'])) + ' cores' - ret.append(self.curse_add_line(msg, splittable=True)) + ret.append(self.curse_add_line(str(len(p['cpu_affinity'])), decoration='INFO')) + ret.append(self.curse_add_line(' cores', decoration='INFO')) + else: + ret.append(self.curse_add_line('N/A', decoration='INFO')) + # and min/max/mean CPU usage + ret.append(self.curse_add_line(' - Min/Max/Mean ')) + msg = '{:.1f}/{:.1f}/{:.1f}%'.format(p['cpu_min'], p['cpu_max'], p['cpu_mean']) + ret.append(self.curse_add_line(msg, decoration='INFO')) + # Second line is memory info if 'memory_info' in p and p['memory_info'] is not None: ret.append(self.curse_new_line()) - msg = 'Memory info: {}'.format(p['memory_info']) + ret.append(self.curse_add_line(' Memory info ')) + msg = ' '.join(['{} {}'.format(k, self.auto_unit(p['memory_info']._asdict()[k], low_precision=False)) for k in p['memory_info']._asdict()]) if 'memory_swap' in p and p['memory_swap'] is not None: msg += ' swap ' + self.auto_unit(p['memory_swap'], low_precision=False) - ret.append(self.curse_add_line(msg, splittable=True)) + ret.append(self.curse_add_line(msg, decoration='INFO', splittable=True)) + # Third line is for open files/network sessions msg = '' if 'num_threads' in p and p['num_threads'] is not None: diff --git a/glances/processes.py b/glances/processes.py index 873983f4..5ec5214c 100644 --- a/glances/processes.py +++ b/glances/processes.py @@ -266,17 +266,20 @@ class GlancesProcesses(object): # - memory_maps (only swap, Linux) # https://www.cyberciti.biz/faq/linux-which-process-is-using-swap/ # - connections (TCP and UDP) + # - CPU min/max/mean + + # Set the extended stats list (OS dependant) + extended_stats = ['cpu_affinity', 'ionice', 'num_ctx_switches'] + if LINUX: + # num_fds only available on Unix system (see issue #1351) + extended_stats += ['num_fds'] + if WINDOWS: + extended_stats += ['num_handles'] + ret = {} try: - selected_process = psutil.Process(proc['pid']) - extended_stats = ['cpu_affinity', 'ionice', 'num_ctx_switches'] - if LINUX: - # num_fds only available on Unix system (see issue #1351) - extended_stats += ['num_fds'] - if WINDOWS: - extended_stats += ['num_handles'] - # Get the extended stats + selected_process = psutil.Process(proc['pid']) ret = selected_process.as_dict(attrs=extended_stats, ad_value=None) if LINUX: @@ -299,10 +302,30 @@ class GlancesProcesses(object): ret['udp'] = None except (psutil.NoSuchProcess, ValueError, AttributeError) as e: logger.error('Can not grab extended stats ({})'.format(e)) - ret['extended_stats'] = False self.extended_process = None + ret['extended_stats'] = False else: logger.debug('Grab extended stats for process {}'.format(proc['pid'])) + + # Compute CPU min/max/mean + if 'cpu_min' not in self.extended_process: + ret['cpu_min'] = proc['cpu_percent'] + else: + ret['cpu_min'] = proc['cpu_percent'] if proc['cpu_min'] > proc['cpu_percent'] else proc['cpu_min'] + if 'cpu_max' not in self.extended_process: + ret['cpu_max'] = proc['cpu_percent'] + else: + ret['cpu_max'] = proc['cpu_percent'] if proc['cpu_max'] < proc['cpu_percent'] else proc['cpu_max'] + if 'cpu_mean_sum' not in self.extended_process: + ret['cpu_mean_sum'] = proc['cpu_percent'] + else: + ret['cpu_mean_sum'] = proc['cpu_mean_sum'] + proc['cpu_percent'] + if 'cpu_mean_counter' not in self.extended_process: + ret['cpu_mean_counter'] = 1 + else: + ret['cpu_mean_counter'] = proc['cpu_mean_counter'] + 1 + ret['cpu_mean'] = ret['cpu_mean_sum'] / ret['cpu_mean_counter'] + ret['extended_stats'] = True return ret @@ -377,16 +400,15 @@ class GlancesProcesses(object): # Extended stats ################ - # Get the selected process + # Get the selected process when the 'e' key is pressed if self.is_selected_process(position): - # logger.info('Selected process: {}'.format(proc)) self.extended_process = proc # Grab extended stats only for the selected process (see issue #2225) if self.extended_process is not None and \ proc['pid'] == self.extended_process['pid']: - self.extended_process = proc proc.update(self.get_extended_stats(self.extended_process)) + self.extended_process = proc # Meta data ########### |