mirror of https://github.com/nicolargo/glances.git
CPU
This commit is contained in:
parent
8d5d993d45
commit
e98cf3c0a4
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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'):
|
||||
|
|
|
|||
Loading…
Reference in New Issue