diff --git a/glances/plugins/core/model.py b/glances/plugins/core/model.py index 579817f3..1cf09b57 100644 --- a/glances/plugins/core/model.py +++ b/glances/plugins/core/model.py @@ -16,12 +16,12 @@ import psutil # Fields description fields_description = { 'phys': { - 'getter': 'self.cpu_count', + 'getter': {'fct': 'self.cpu_count', 'arg': {}}, 'description': 'Number of physical cores (hyper thread CPUs are excluded).', 'unit': 'number' }, 'log': { - 'getter': 'self.cpu_count', + 'getter': {'fct': 'self.cpu_count', 'arg': {}}, 'description': 'Number of logical CPUs. A logical CPU is the number of \ physical cores multiplied by the number of threads that can run on each core.', 'unit': 'number', diff --git a/glances/plugins/cpu/model.py b/glances/plugins/cpu/model.py index f555c8ae..b8fc2734 100644 --- a/glances/plugins/cpu/model.py +++ b/glances/plugins/cpu/model.py @@ -24,50 +24,63 @@ import psutil # rate: is it a rate ? If yes, // by time_since_update when displayed, # min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)... fields_description = { - 'total': {'description': 'Sum of all CPU percentages (except idle).', 'unit': 'percent'}, + 'total': { + # 'getter': 'compute', + 'description': 'Sum of all CPU percentages (except idle).', + 'unit': 'percent' + }, 'system': { + 'getter': {'fct': 'psutil.cpu_times_percent', 'arg': {'interval': 0.0}}, 'description': 'percent time spent in kernel space. System CPU time is the \ time spent running code in the Operating System kernel.', 'unit': 'percent', }, 'user': { + 'getter': {'fct': 'psutil.cpu_times_percent', 'arg': {'interval': 0.0}}, 'description': 'CPU percent time spent in user space. \ User CPU time is the time spent on the processor running your program\'s code (or code in libraries).', 'unit': 'percent', }, 'iowait': { + 'getter': {'fct': 'psutil.cpu_times_percent', 'arg': {'interval': 0.0}}, 'description': '*(Linux)*: percent time spent by the CPU waiting for I/O \ operations to complete.', 'unit': 'percent', }, 'dpc': { + 'getter': {'fct': 'psutil.cpu_times_percent', 'arg': {'interval': 0.0}}, 'description': '*(Windows)*: time spent servicing deferred procedure calls (DPCs)', 'unit': 'percent', }, 'idle': { + 'getter': {'fct': 'psutil.cpu_times_percent', 'arg': {'interval': 0.0}}, 'description': 'percent of CPU used by any program. Every program or task \ that runs on a computer system occupies a certain amount of processing \ time on the CPU. If the CPU has completed all tasks it is idle.', 'unit': 'percent', }, 'irq': { + 'getter': {'fct': 'psutil.cpu_times_percent', 'arg': {'interval': 0.0}}, 'description': '*(Linux and BSD)*: percent time spent servicing/handling \ hardware/software interrupts. Time servicing interrupts (hardware + \ software).', 'unit': 'percent', }, 'nice': { + 'getter': {'fct': 'psutil.cpu_times_percent', 'arg': {'interval': 0.0}}, 'description': '*(Unix)*: percent time occupied by user level processes with \ a positive nice value. The time the CPU has spent running users\' \ processes that have been *niced*.', 'unit': 'percent', }, 'steal': { + 'getter': {'fct': 'psutil.cpu_times_percent', 'arg': {'interval': 0.0}}, 'description': '*(Linux)*: percentage of time a virtual CPU waits for a real \ CPU while the hypervisor is servicing another virtual processor.', 'unit': 'percent', }, 'ctx_switches': { + 'getter': {'fct': 'psutil.cpu_stats', 'arg': {}}, 'description': 'number of context switches (voluntary + involuntary) per \ second. A context switch is a procedure that a computer\'s CPU (central \ processing unit) follows to change from one task (or process) to \ @@ -78,6 +91,7 @@ another while ensuring that the tasks do not conflict.', 'short_name': 'ctx_sw', }, 'interrupts': { + 'getter': {'fct': 'psutil.cpu_stats', 'arg': {}}, 'description': 'number of interrupts per second.', 'unit': 'number', 'rate': True, @@ -85,6 +99,7 @@ another while ensuring that the tasks do not conflict.', 'short_name': 'inter', }, 'soft_interrupts': { + 'getter': {'fct': 'psutil.cpu_stats', 'arg': {}}, 'description': 'number of software interrupts per second. Always set to \ 0 on Windows and SunOS.', 'unit': 'number', @@ -93,6 +108,7 @@ another while ensuring that the tasks do not conflict.', 'short_name': 'sw_int', }, 'syscalls': { + 'getter': {'fct': 'psutil.cpu_stats', 'arg': {}}, 'description': 'number of system calls per second. Always 0 on Linux OS.', 'unit': 'number', 'rate': True, @@ -159,9 +175,9 @@ class PluginModel(GlancesPluginModel): """Update CPU stats using the input method.""" # Grab stats into self.stats if self.input_method == 'local': - stats = self.update_local() + stats = self.update_cpu_local() elif self.input_method == 'snmp': - stats = self.update_snmp() + stats = self.update_cpu_snmp() else: stats = self.get_init_value() @@ -170,7 +186,7 @@ class PluginModel(GlancesPluginModel): return self.stats - def update_local(self): + def update_cpu_local(self): """Update CPU stats using psutil.""" # Grab CPU stats using psutil's cpu_percent and cpu_times_percent # Get all possible values for CPU stats: user, system, idle, @@ -199,16 +215,19 @@ class PluginModel(GlancesPluginModel): # under the control of the Linux kernel) # - interrupt (Windows): time spent for servicing hardware interrupts ( similar to “irq” on UNIX) # - dpc (Windows): time spent servicing deferred procedure calls (DPCs) - cpu_times_percent = psutil.cpu_times_percent(interval=0.0) - for stat in cpu_times_percent._fields: - stats[stat] = getattr(cpu_times_percent, stat) + + # cpu_times_percent = psutil.cpu_times_percent(interval=0.0) + # for stat in cpu_times_percent._fields: + # stats[stat] = getattr(cpu_times_percent, stat) # Additional CPU stats (number of events not as a %; psutil>=4.1.0) # - ctx_switches: number of context switches (voluntary + involuntary) since boot. # - interrupts: number of interrupts since boot. # - soft_interrupts: number of software interrupts since boot. Always set to 0 on Windows and SunOS. # - syscalls: number of system calls since boot. Always set to 0 on Linux. - cpu_stats = psutil.cpu_stats() + + # cpu_stats = psutil.cpu_stats() + self.update_local(stats) # By storing time data we enable Rx/s and Tx/s calculations in the # XML/RPC API, which would otherwise be overly difficult work @@ -218,24 +237,24 @@ class PluginModel(GlancesPluginModel): # Core number is needed to compute the CTX switch limit stats['cpucore'] = self.nb_log_core - # Previous CPU stats are stored in the cpu_stats_old variable - if not hasattr(self, 'cpu_stats_old'): - # Init the stats (needed to have the key name for export) - for stat in cpu_stats._fields: - # @TODO: better to set it to None but should refactor views and UI... - stats[stat] = 0 - else: - # Others calls... - for stat in cpu_stats._fields: - if getattr(cpu_stats, stat) is not None: - stats[stat] = getattr(cpu_stats, stat) - getattr(self.cpu_stats_old, stat) + # # Previous CPU stats are stored in the cpu_stats_old variable + # if not hasattr(self, 'stats_old'): + # # Init the stats (needed to have the key name for export) + # for stat in stats: + # # @TODO: better to set it to None but should refactor views and UI... + # stats[stat] = 0 + # else: + # # Others calls... + # for stat in stats: + # if stat in stats: + # stats[stat] = stats[stat] - self.stats_old[stat] - # Save stats to compute next step - self.cpu_stats_old = cpu_stats + # # Save stats to compute next step + # self.stats_old = stats return stats - def update_snmp(self): + def update_cpu_snmp(self): """Update CPU stats using SNMP.""" # Init new stats diff --git a/glances/plugins/mem/model.py b/glances/plugins/mem/model.py index 5d5684bb..8ccea841 100644 --- a/glances/plugins/mem/model.py +++ b/glances/plugins/mem/model.py @@ -15,13 +15,13 @@ from glances.plugins.plugin.model import GlancesPluginModel # Fields description fields_description = { 'total': { - 'getter': 'psutil.virtual_memory', + 'getter': {'fct': 'psutil.virtual_memory', 'arg': {}}, 'description': 'Total physical memory available.', 'unit': 'bytes', 'min_symbol': 'K' }, 'available': { - 'getter': 'psutil.virtual_memory', + 'getter': {'fct': 'psutil.virtual_memory', 'arg': {}}, 'description': 'The actual amount of available memory that can be given instantly \ to processes that request more memory in bytes; this is calculated by summing \ different memory values depending on the platform (e.g. free + buffers + cached on Linux) \ @@ -30,44 +30,44 @@ and it is supposed to be used to monitor actual memory usage in a cross platform 'min_symbol': 'K', }, 'percent': { - 'getter': 'psutil.virtual_memory', + 'getter': {'fct': 'psutil.virtual_memory', 'arg': {}}, 'description': 'The percentage usage calculated as (total - available) / total * 100.', 'unit': 'percent', }, 'active': { - 'getter': 'psutil.virtual_memory', + 'getter': {'fct': 'psutil.virtual_memory', 'arg': {}}, 'description': '*(UNIX)*: memory currently in use or very recently used, and so it is in RAM.', 'unit': 'bytes', 'min_symbol': 'K', }, 'inactive': { - 'getter': 'psutil.virtual_memory', + 'getter': {'fct': 'psutil.virtual_memory', 'arg': {}}, 'description': '*(UNIX)*: memory that is marked as not used.', 'unit': 'bytes', 'min_symbol': 'K', 'short_name': 'inacti', }, 'buffers': { - 'getter': 'psutil.virtual_memory', + 'getter': {'fct': 'psutil.virtual_memory', 'arg': {}}, 'description': '*(Linux, BSD)*: cache for things like file system metadata.', 'unit': 'bytes', 'min_symbol': 'K', 'short_name': 'buffer', }, 'cached': { - 'getter': 'psutil.virtual_memory', + 'getter': {'fct': 'psutil.virtual_memory', 'arg': {}}, 'description': '*(Linux, BSD)*: cache for various things.', 'unit': 'bytes', 'min_symbol': 'K' }, 'wired': { - 'getter': 'psutil.virtual_memory', + 'getter': {'fct': 'psutil.virtual_memory', 'arg': {}}, 'description': '*(BSD, macOS)*: memory that is marked to always stay in RAM. It is never moved to disk.', 'unit': 'bytes', 'min_symbol': 'K', }, 'shared': { - 'getter': 'psutil.virtual_memory', + 'getter': {'fct': 'psutil.virtual_memory', 'arg': {}}, 'description': '*(BSD)*: memory that may be simultaneously accessed by multiple processes.', 'unit': 'bytes', 'min_symbol': 'K', diff --git a/glances/plugins/memswap/model.py b/glances/plugins/memswap/model.py index eb04314e..ef2485e3 100644 --- a/glances/plugins/memswap/model.py +++ b/glances/plugins/memswap/model.py @@ -17,36 +17,36 @@ import psutil # Fields description fields_description = { 'total': { - 'getter': 'psutil.swap_memory', + 'getter': {'fct': 'psutil.swap_memory', 'arg': {}}, 'description': 'Total swap memory.', 'unit': 'bytes', 'min_symbol': 'K' }, 'used': { - 'getter': 'psutil.swap_memory', + 'getter': {'fct': 'psutil.swap_memory', 'arg': {}}, 'description': 'Used swap memory.', 'unit': 'bytes', 'min_symbol': 'K' }, 'free': { - 'getter': 'psutil.swap_memory', + 'getter': {'fct': 'psutil.swap_memory', 'arg': {}}, 'description': 'Free swap memory.', 'unit': 'bytes', 'min_symbol': 'K' }, 'percent': { - 'getter': 'psutil.swap_memory', + 'getter': {'fct': 'psutil.swap_memory', 'arg': {}}, 'description': 'Used swap memory in percentage.', 'unit': 'percent' }, 'sin': { - 'getter': 'psutil.swap_memory', + 'getter': {'fct': 'psutil.swap_memory', 'arg': {}}, 'description': 'The number of bytes the system has swapped in from disk (cumulative).', 'unit': 'bytes', 'min_symbol': 'K', }, 'sout': { - 'getter': 'psutil.swap_memory', + 'getter': {'fct': 'psutil.swap_memory', 'arg': {}}, 'description': 'The number of bytes the system has swapped out from disk (cumulative).', 'unit': 'bytes', 'min_symbol': 'K', diff --git a/glances/plugins/plugin/model.py b/glances/plugins/plugin/model.py index ba33acff..30013a55 100644 --- a/glances/plugins/plugin/model.py +++ b/glances/plugins/plugin/model.py @@ -114,19 +114,20 @@ class GlancesPluginModel(object): # Init stats description self.fields_description = fields_description if fields_description: - # Return a list of getter (internal or external functions to run to get the stats) - # Note: It should return a dict - self.getters = list(set([fields_description[i]['getter'] for i in fields_description - if (i in fields_description and - 'getter' in fields_description[i] and - fields_description[i]['getter'] not in ('compute'))])) - # Return a list of internal functions to run to compute the stats + # Return a dict of getter (internal or external functions to run to get the stats) + # key: getter name (string) + # value: arguments + # return: a dict + self.getters = {fields_description[i]['getter']['fct']:fields_description[i]['getter']['arg'] for i in fields_description + if ('getter' in fields_description[i] and + 'fct' in fields_description[i]['getter'])} + # Return a list of internal functions to be ran to compute the stats # Computation is done after the getters - # Note It could return what ever you want + # return: what you want, but should be JSON serializable self.computes = [i for i in fields_description if (i in fields_description and 'getter' in fields_description[i] and - fields_description[i]['getter'] in ('compute'))] + fields_description[i]['getter'] == 'compute')] else: self.getters = [] self.computes = [] @@ -198,12 +199,16 @@ class GlancesPluginModel(object): """Return the stats updated from the getters functions.""" for g in self.getters: # For each "getter", the Python function is called - g_lib = g.split('.')[0] - g_func = g.split('.')[1] - if g_lib == 'self': - g_call = getattr(self, g_func)() + g_lib_name, g_func = g.split('.') + g_arg = self.getters.get(g, None) + if g_lib_name == 'self': + g_lib = self else: - g_call = getattr(globals()[g_lib], g_func)() + g_lib = globals()[g_lib_name] + if g_arg: + g_call = getattr(g_lib, g_func)(**g_arg) + else: + g_call = getattr(g_lib, g_func)() # The result is stored in the stats dict # (only if the field is in the self.fields_description) if hasattr(g_call, '_fields'):