summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicolargo <nicolas@nicolargo.com>2022-12-29 12:05:01 +0100
committernicolargo <nicolas@nicolargo.com>2022-12-29 12:05:01 +0100
commitab68b362a11a256560646050a06568e875ea54be (patch)
treeb38036d13ea267ca05a6ad899aa8405abf41b733
parentd6bdb8dd8e5be7495f842a480ee88aaedf04078e (diff)
CPU and MEM ok
-rw-r--r--glances/outputs/glances_curses.py3
-rw-r--r--glances/plugins/glances_processlist.py31
-rw-r--r--glances/processes.py46
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
###########