diff options
Diffstat (limited to 'glances/plugins/quicklook/__init__.py')
-rw-r--r-- | glances/plugins/quicklook/__init__.py | 110 |
1 files changed, 76 insertions, 34 deletions
diff --git a/glances/plugins/quicklook/__init__.py b/glances/plugins/quicklook/__init__.py index 862eb243..5fc46ac2 100644 --- a/glances/plugins/quicklook/__init__.py +++ b/glances/plugins/quicklook/__init__.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# SPDX-FileCopyrightText: 2022 Nicolas Hennion <nicolas@nicolargo.com> +# SPDX-FileCopyrightText: 2024 Nicolas Hennion <nicolas@nicolargo.com> # # SPDX-License-Identifier: LGPL-3.0-only # @@ -11,6 +11,7 @@ from glances.logger import logger from glances.cpu_percent import cpu_percent +from glances.plugins.load import get_load_average, get_nb_log_core from glances.outputs.glances_bars import Bar from glances.outputs.glances_sparklines import Sparkline from glances.plugins.plugin.model import GlancesPluginModel @@ -36,6 +37,10 @@ fields_description = { 'description': 'SWAP percent usage', 'unit': 'percent', }, + 'load': { + 'description': 'LOAD percent usage', + 'unit': 'percent', + }, 'cpu_name': { 'description': 'CPU name', }, @@ -56,6 +61,7 @@ items_history_list = [ {'name': 'percpu', 'description': 'PERCPU percent usage', 'y_unit': '%'}, {'name': 'mem', 'description': 'MEM percent usage', 'y_unit': '%'}, {'name': 'swap', 'description': 'SWAP percent usage', 'y_unit': '%'}, + {'name': 'load', 'description': 'LOAD percent usage', 'y_unit': '%'}, ] @@ -65,6 +71,9 @@ class PluginModel(GlancesPluginModel): 'stats' is a dictionary. """ + AVAILABLE_STATS_LIST = ['cpu', 'mem', 'swap', 'load'] + DEFAULT_STATS_LIST = ['cpu', 'mem', 'load'] + def __init__(self, args=None, config=None): """Init the quicklook plugin.""" super(PluginModel, self).__init__( @@ -75,6 +84,12 @@ class PluginModel(GlancesPluginModel): # We want to display the stat in the curse interface self.display_curse = True + # Define the stats list + self.stats_list = self.get_conf_value('list', default=self.DEFAULT_STATS_LIST) + if not set(self.stats_list).issubset(self.AVAILABLE_STATS_LIST): + logger.warning('Quicklook plugin: Invalid stats list: {}'.format(self.stats_list)) + self.stats_list = self.AVAILABLE_STATS_LIST + @GlancesPluginModel._check_decorator @GlancesPluginModel._log_result_decorator def update(self): @@ -84,11 +99,20 @@ class PluginModel(GlancesPluginModel): # Grab quicklook stats: CPU, MEM and SWAP if self.input_method == 'local': - # Get the latest CPU percent value + # Get system information + cpu_info = cpu_percent.get_info() + stats['cpu_name'] = cpu_info['cpu_name'] + stats['cpu_hz_current'] = ( + self._mhz_to_hz(cpu_info['cpu_hz_current']) if cpu_info['cpu_hz_current'] is not None else None + ) + stats['cpu_hz'] = self._mhz_to_hz(cpu_info['cpu_hz']) if cpu_info['cpu_hz'] is not None else None + + # Get the CPU percent value (global and per core) + # Stats is shared across all plugins stats['cpu'] = cpu_percent.get() stats['percpu'] = cpu_percent.get(percpu=True) - # Use the psutil lib for the memory (virtual and swap) + # Get the virtual and swap memory stats['mem'] = psutil.virtual_memory().percent try: stats['swap'] = psutil.swap_memory().percent @@ -96,13 +120,14 @@ class PluginModel(GlancesPluginModel): # Correct issue in Illumos OS (see #1767) stats['swap'] = None - # Get additional information - cpu_info = cpu_percent.get_info() - stats['cpu_name'] = cpu_info['cpu_name'] - stats['cpu_hz_current'] = ( - self._mhz_to_hz(cpu_info['cpu_hz_current']) if cpu_info['cpu_hz_current'] is not None else None - ) - stats['cpu_hz'] = self._mhz_to_hz(cpu_info['cpu_hz']) if cpu_info['cpu_hz'] is not None else None + # Get load + stats['cpucore'] = get_nb_log_core() + try: + # Load average is a tuple (1 min, 5 min, 15 min) + # Process only the 15 min value (index 2) + stats['load'] = get_load_average(percent=True)[2] + except (TypeError, IndexError): + stats['load'] = None elif self.input_method == 'snmp': # Not available @@ -118,12 +143,19 @@ class PluginModel(GlancesPluginModel): # Call the father's method super(PluginModel, self).update_views() - # Add specifics information - # Alert only - for key in ['cpu', 'mem', 'swap']: + # Alert for CPU, MEM and SWAP + for key in self.stats_list: if key in self.stats: self.views[key]['decoration'] = self.get_alert(self.stats[key], header=key) + # Alert for LOAD + self.views['load']['decoration'] = self.get_alert( + self.stats['load'], header='load' + ) + + # Define the list of stats to display + self.views['list'] = self.stats_list + def msg_curse(self, args=None, max_width=10): """Return the list to display in the UI.""" # Init the return message @@ -139,15 +171,19 @@ class PluginModel(GlancesPluginModel): return ret # Define the data: Bar (default behavior) or Sparkline - sparkline_tag = False - if self.args.sparkline and self.history_enable() and not self.args.client: - data = Sparkline(max_width) - sparkline_tag = data.available - if not sparkline_tag: - # Fallback to bar if Sparkline module is not installed - data = Bar(max_width, percentage_char=self.get_conf_value('percentage_char', default=['|'])[0]) + data = dict() + for key in self.stats_list: + if self.args.sparkline and self.history_enable() and not self.args.client: + data[key] = Sparkline(max_width) + else: + # Fallback to bar if Sparkline module is not installed + data[key] = Bar(max_width, + bar_char=self.get_conf_value('bar_char', default=['|'])[0]) # Build the string message + ########################## + + # System information if 'cpu_name' in self.stats and 'cpu_hz_current' in self.stats and 'cpu_hz' in self.stats: msg_name = self.stats['cpu_name'] if self.stats['cpu_hz_current'] and self.stats['cpu_hz']: @@ -160,36 +196,38 @@ class PluginModel(GlancesPluginModel): ret.append(self.curse_add_line(msg_name)) ret.append(self.curse_add_line(msg_freq)) ret.append(self.curse_new_line()) - for key in ['cpu', 'mem', 'swap']: + + # Loop over CPU, MEM and LOAD + for key in self.stats_list: if key == 'cpu' and args.percpu: - if sparkline_tag: - raw_cpu = self.get_raw_history(item='percpu', nb=data.size) + if type(data[key]).__name__ == 'Sparkline': + raw_cpu = self.get_raw_history(item='percpu', nb=data[key].size) for cpu_index, cpu in enumerate(self.stats['percpu']): - if sparkline_tag: + if type(data[key]).__name__ == 'Sparkline': # Sparkline display an history - data.percents = [i[1][cpu_index]['total'] for i in raw_cpu] + data[key].percents = [i[1][cpu_index]['total'] for i in raw_cpu] # A simple padding in order to align metrics to the right - data.percents += [None] * (data.size - len(data.percents)) + data[key].percents += [None] * (data[key].size - len(data[key].percents)) else: # Bar only the last value - data.percent = cpu['total'] + data[key].percent = cpu['total'] if cpu[cpu['key']] < 10: msg = '{:3}{} '.format(key.upper(), cpu['cpu_number']) else: msg = '{:4} '.format(cpu['cpu_number']) - ret.extend(self._msg_create_line(msg, data, key)) + ret.extend(self._msg_create_line(msg, data[key], key)) ret.append(self.curse_new_line()) else: - if sparkline_tag: + if type(data[key]).__name__ == 'Sparkline': # Sparkline display an history - data.percents = [i[1] for i in self.get_raw_history(item=key, nb=data.size)] + data[key].percents = [i[1] for i in self.get_raw_history(item=key, nb=data[key].size)] # A simple padding in order to align metrics to the right - data.percents += [None] * (data.size - len(data.percents)) + data[key].percents += [None] * (data[key].size - len(data[key].percents)) else: # Bar only the last value - data.percent = self.stats[key] + data[key].percent = self.stats[key] msg = '{:4} '.format(key.upper()) - ret.extend(self._msg_create_line(msg, data, key)) + ret.extend(self._msg_create_line(msg, data[key], key)) ret.append(self.curse_new_line()) # Remove the last new line @@ -200,10 +238,14 @@ class PluginModel(GlancesPluginModel): def _msg_create_line(self, msg, data, key): """Create a new line to the Quick view.""" + # if key == 'mem' and self.get_alert(self.stats['swap'], header='swap') != 'DEFAULT': + # overwrite = 'SWAP' + # else: + overwrite = '' return [ self.curse_add_line(msg), self.curse_add_line(data.pre_char, decoration='BOLD'), - self.curse_add_line(data.get(), self.get_views(key=key, option='decoration')), + self.curse_add_line(data.get(overwrite), self.get_views(key=key, option='decoration')), self.curse_add_line(data.post_char, decoration='BOLD'), self.curse_add_line(' '), ] |