CPU and MEM ok

This commit is contained in:
nicolargo 2022-12-29 12:05:01 +01:00
parent d6bdb8dd8e
commit ab68b362a1
3 changed files with 60 additions and 20 deletions

View File

@ -268,6 +268,7 @@ class _GlancesCurses(object):
self.ifCAREFUL_color2 = curses.color_pair(8) | A_BOLD self.ifCAREFUL_color2 = curses.color_pair(8) | A_BOLD
self.ifWARNING_color2 = curses.color_pair(5) | A_BOLD self.ifWARNING_color2 = curses.color_pair(5) | A_BOLD
self.ifCRITICAL_color2 = curses.color_pair(6) | A_BOLD self.ifCRITICAL_color2 = curses.color_pair(6) | A_BOLD
self.ifINFO_color = curses.color_pair(8)
self.filter_color = A_BOLD self.filter_color = A_BOLD
self.selected_color = A_BOLD self.selected_color = A_BOLD
@ -301,6 +302,7 @@ class _GlancesCurses(object):
self.ifCAREFUL_color2 = curses.A_UNDERLINE self.ifCAREFUL_color2 = curses.A_UNDERLINE
self.ifWARNING_color2 = A_BOLD self.ifWARNING_color2 = A_BOLD
self.ifCRITICAL_color2 = curses.A_REVERSE self.ifCRITICAL_color2 = curses.A_REVERSE
self.ifINFO_color = A_BOLD
self.filter_color = A_BOLD self.filter_color = A_BOLD
self.selected_color = A_BOLD self.selected_color = A_BOLD
@ -328,6 +330,7 @@ class _GlancesCurses(object):
'CRITICAL_LOG': self.ifCRITICAL_color, 'CRITICAL_LOG': self.ifCRITICAL_color,
'PASSWORD': curses.A_PROTECT, 'PASSWORD': curses.A_PROTECT,
'SELECTED': self.selected_color, 'SELECTED': self.selected_color,
'INFO': self.ifINFO_color
} }
def set_cursor(self, value): def set_cursor(self, value):

View File

@ -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_core import Plugin as CorePlugin
from glances.plugins.glances_plugin import GlancesPlugin from glances.plugins.glances_plugin import GlancesPlugin
from glances.programs import processes_to_programs from glances.programs import processes_to_programs
from glances.outputs.glances_bars import Bar
def seconds_to_hms(input_seconds): def seconds_to_hms(input_seconds):
@ -502,7 +503,10 @@ class Plugin(GlancesPlugin):
'key': 'pid', 'key': 'pid',
'time_since_update': 2.1997854709625244, 'time_since_update': 2.1997854709625244,
'cmdline': ['/snap/firefox/2154/usr/lib/firefox/firefox', '-contentproc', '-childID', '...'], '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: if self.args.programs:
self.__msg_curse_extended_process_program(ret, p) self.__msg_curse_extended_process_program(ret, p)
@ -519,21 +523,32 @@ class Plugin(GlancesPlugin):
def __msg_curse_extended_process_thread(self, ret, p): def __msg_curse_extended_process_thread(self, ret, p):
# Title # Title
msg = "Pinned thread {} ('e' to unpin)".format(p['name']) ret.append(self.curse_add_line("Pinned thread ", "TITLE"))
ret.append(self.curse_add_line(msg, "TITLE")) ret.append(self.curse_add_line(p['name'], "UNDERLINE"))
ret.append(self.curse_add_line(" ('e' to unpin)"))
# First line is CPU affinity # First line is CPU affinity
if 'cpu_affinity' in p and p['cpu_affinity'] is not None:
ret.append(self.curse_new_line()) ret.append(self.curse_new_line())
msg = 'CPU affinity: ' + str(len(p['cpu_affinity'])) + ' cores' ret.append(self.curse_add_line(' CPU affinity '))
ret.append(self.curse_add_line(msg, splittable=True)) if 'cpu_affinity' in p and p['cpu_affinity'] is not None:
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 # Second line is memory info
if 'memory_info' in p and p['memory_info'] is not None: if 'memory_info' in p and p['memory_info'] is not None:
ret.append(self.curse_new_line()) 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: if 'memory_swap' in p and p['memory_swap'] is not None:
msg += ' swap ' + self.auto_unit(p['memory_swap'], low_precision=False) 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 # Third line is for open files/network sessions
msg = '' msg = ''
if 'num_threads' in p and p['num_threads'] is not None: if 'num_threads' in p and p['num_threads'] is not None:

View File

@ -266,9 +266,9 @@ class GlancesProcesses(object):
# - memory_maps (only swap, Linux) # - memory_maps (only swap, Linux)
# https://www.cyberciti.biz/faq/linux-which-process-is-using-swap/ # https://www.cyberciti.biz/faq/linux-which-process-is-using-swap/
# - connections (TCP and UDP) # - connections (TCP and UDP)
ret = {} # - CPU min/max/mean
try:
selected_process = psutil.Process(proc['pid']) # Set the extended stats list (OS dependant)
extended_stats = ['cpu_affinity', 'ionice', 'num_ctx_switches'] extended_stats = ['cpu_affinity', 'ionice', 'num_ctx_switches']
if LINUX: if LINUX:
# num_fds only available on Unix system (see issue #1351) # num_fds only available on Unix system (see issue #1351)
@ -276,7 +276,10 @@ class GlancesProcesses(object):
if WINDOWS: if WINDOWS:
extended_stats += ['num_handles'] extended_stats += ['num_handles']
ret = {}
try:
# Get the extended stats # Get the extended stats
selected_process = psutil.Process(proc['pid'])
ret = selected_process.as_dict(attrs=extended_stats, ad_value=None) ret = selected_process.as_dict(attrs=extended_stats, ad_value=None)
if LINUX: if LINUX:
@ -299,10 +302,30 @@ class GlancesProcesses(object):
ret['udp'] = None ret['udp'] = None
except (psutil.NoSuchProcess, ValueError, AttributeError) as e: except (psutil.NoSuchProcess, ValueError, AttributeError) as e:
logger.error('Can not grab extended stats ({})'.format(e)) logger.error('Can not grab extended stats ({})'.format(e))
ret['extended_stats'] = False
self.extended_process = None self.extended_process = None
ret['extended_stats'] = False
else: else:
logger.debug('Grab extended stats for process {}'.format(proc['pid'])) 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 ret['extended_stats'] = True
return ret return ret
@ -377,16 +400,15 @@ class GlancesProcesses(object):
# Extended stats # Extended stats
################ ################
# Get the selected process # Get the selected process when the 'e' key is pressed
if self.is_selected_process(position): if self.is_selected_process(position):
# logger.info('Selected process: {}'.format(proc))
self.extended_process = proc self.extended_process = proc
# Grab extended stats only for the selected process (see issue #2225) # Grab extended stats only for the selected process (see issue #2225)
if self.extended_process is not None and \ if self.extended_process is not None and \
proc['pid'] == self.extended_process['pid']: proc['pid'] == self.extended_process['pid']:
self.extended_process = proc
proc.update(self.get_extended_stats(self.extended_process)) proc.update(self.get_extended_stats(self.extended_process))
self.extended_process = proc
# Meta data # Meta data
########### ###########