提交 73f091f2 编写于 作者: N nicolargo

Refactor CPU Curses code

上级 5b5cb1ce
......@@ -30,6 +30,11 @@ from glances.plugins.glances_plugin import GlancesPlugin
import psutil
# Fields description
# description: human readable description
# short_name: shortname to use un UI
# unit: unit type
# 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'},
......@@ -61,12 +66,21 @@ CPU while the hypervisor is servicing another virtual processor.',
second. A context switch is a procedure that a computer\'s CPU (central \
processing unit) follows to change from one task (or process) to \
another while ensuring that the tasks do not conflict.',
'unit': 'percent'},
'unit': 'number',
'rate': True,
'min_symbol': 'K',
'short_name': 'ctx_sw'},
'interrupts': {'description': 'number of interrupts per second.',
'unit': 'percent'},
'unit': 'number',
'rate': True,
'min_symbol': 'K',
'short_name': 'inter'},
'soft_interrupts': {'description': 'number of software interrupts per second. Always set to \
0 on Windows and SunOS.',
'unit': 'percent'},
'unit': 'number',
'rate': True,
'min_symbol': 'K',
'short_name': 'sw_int'},
'cpucore': {'description': 'Total number of CPU core.',
'unit': 'number'},
'time_since_update': {'description': 'Number of seconds since last update.',
......@@ -290,102 +304,50 @@ class Plugin(GlancesPlugin):
msg, self.get_views(key='total', option='decoration')))
# Idle CPU
if 'idle' in self.stats and not idle_tag:
msg = ' {:8}'.format('idle:')
ret.append(self.curse_add_line(msg))
msg = '{:5.1f}%'.format(self.stats['idle'])
ret.append(self.curse_add_line(msg))
# ctx_switches
if 'ctx_switches' in self.stats:
msg = ' {:8}'.format('ctx_sw:')
ret.append(self.curse_add_line(msg, optional=self.get_views(key='ctx_switches', option='optional')))
msg = '{:>5}'.format(self.auto_unit(int(self.stats['ctx_switches'] // self.stats['time_since_update']),
min_symbol='K'))
ret.append(self.curse_add_line(
msg, self.get_views(key='ctx_switches', option='decoration'),
optional=self.get_views(key='ctx_switches', option='optional')))
ret.extend(self.curse_add_stat('idle', width=15, header=' '))
# ctx_switches
if 'ctx_switches' in self.stats:
ret.extend(self.curse_add_stat('ctx_switches', width=15, header=' '))
# New line
ret.append(self.curse_new_line())
# User CPU
if 'user' in self.stats:
msg = '{:8}'.format('user:')
ret.append(self.curse_add_line(msg))
msg = '{:5.1f}%'.format(self.stats['user'])
ret.append(self.curse_add_line(
msg, self.get_views(key='user', option='decoration')))
ret.extend(self.curse_add_stat('user', width=15))
elif 'idle' in self.stats:
msg = '{:8}'.format('idle:')
ret.append(self.curse_add_line(msg))
msg = '{:5.1f}%'.format(self.stats['idle'])
ret.append(self.curse_add_line(msg))
ret.extend(self.curse_add_stat('idle', width=15))
# IRQ CPU
if 'irq' in self.stats:
msg = ' {:8}'.format('irq:')
ret.append(self.curse_add_line(msg, optional=self.get_views(key='irq', option='optional')))
msg = '{:5.1f}%'.format(self.stats['irq'])
ret.append(self.curse_add_line(msg, optional=self.get_views(key='irq', option='optional')))
# interrupts
if 'interrupts' in self.stats:
msg = ' {:8}'.format('inter:')
ret.append(self.curse_add_line(msg, optional=self.get_views(key='interrupts', option='optional')))
msg = '{:>5}'.format(int(self.stats['interrupts'] // self.stats['time_since_update']))
ret.append(self.curse_add_line(msg, optional=self.get_views(key='interrupts', option='optional')))
ret.extend(self.curse_add_stat('irq', width=15, header=' '))
# interrupts
if 'interrupts' in self.stats:
ret.extend(self.curse_add_stat('interrupts', width=15, header=' '))
# New line
ret.append(self.curse_new_line())
# System CPU
if 'system' in self.stats and not idle_tag:
msg = '{:8}'.format('system:')
ret.append(self.curse_add_line(msg))
msg = '{:5.1f}%'.format(self.stats['system'])
ret.append(self.curse_add_line(
msg, self.get_views(key='system', option='decoration')))
ret.extend(self.curse_add_stat('system', width=15))
else:
msg = '{:8}'.format('core:')
ret.append(self.curse_add_line(msg))
msg = '{:>6}'.format(self.stats['nb_log_core'])
ret.append(self.curse_add_line(msg))
ret.extend(self.curse_add_stat('core', width=15))
# Nice CPU
if 'nice' in self.stats:
msg = ' {:8}'.format('nice:')
ret.append(self.curse_add_line(
msg, optional=self.get_views(key='nice', option='optional')))
msg = '{:5.1f}%'.format(self.stats['nice'])
ret.append(self.curse_add_line(
msg, optional=self.get_views(key='nice', option='optional')))
# soft_interrupts
if 'soft_interrupts' in self.stats:
msg = ' {:8}'.format('sw_int:')
ret.append(self.curse_add_line(msg, optional=self.get_views(key='soft_interrupts', option='optional')))
msg = '{:>5}'.format(int(self.stats['soft_interrupts'] // self.stats['time_since_update']))
ret.append(self.curse_add_line(msg, optional=self.get_views(key='soft_interrupts', option='optional')))
ret.extend(self.curse_add_stat('nice', width=15, header=' '))
# soft_interrupts
if 'soft_interrupts' in self.stats:
ret.extend(self.curse_add_stat('soft_interrupts', width=15, header=' '))
# New line
ret.append(self.curse_new_line())
# IOWait CPU
if 'iowait' in self.stats:
msg = '{:8}'.format('iowait:')
ret.append(self.curse_add_line(
msg, optional=self.get_views(key='iowait', option='optional')))
msg = '{:5.1f}%'.format(self.stats['iowait'])
ret.append(self.curse_add_line(
msg, self.get_views(key='iowait', option='decoration'),
optional=self.get_views(key='iowait', option='optional')))
# Steal CPU usage
if 'steal' in self.stats:
msg = ' {:8}'.format('steal:')
ret.append(self.curse_add_line(msg, optional=self.get_views(key='steal', option='optional')))
msg = '{:5.1f}%'.format(self.stats['steal'])
ret.append(self.curse_add_line(
msg, self.get_views(key='steal', option='decoration'),
optional=self.get_views(key='steal', option='optional')))
# syscalls
ret.extend(self.curse_add_stat('iowait', width=15))
# Steal CPU usage
if 'steal' in self.stats:
ret.extend(self.curse_add_stat('steal', width=15, header=' '))
# syscalls: number of system calls since boot. Always set to 0 on Linux. (do not display)
if 'syscalls' in self.stats and not LINUX:
msg = ' {:8}'.format('syscal:')
ret.append(self.curse_add_line(msg, optional=self.get_views(key='syscalls', option='optional')))
msg = '{:>5}'.format(int(self.stats['syscalls'] // self.stats['time_since_update']))
ret.append(self.curse_add_line(msg, optional=self.get_views(key='syscalls', option='optional')))
ret.extend(self.curse_add_stat('syscalls', width=15, header=' '))
# Return the message with decoration
return ret
......@@ -37,6 +37,17 @@ from glances.thresholds import glances_thresholds
from glances.timer import Counter, Timer
fields_unit_short = {
'percent': '%'
}
fields_unit_type = {
'percent': 'float',
'number': 'int',
'seconds': 'int'
}
class GlancesPlugin(object):
"""Main class for Glances plugin."""
......@@ -169,8 +180,8 @@ class GlancesPlugin(object):
def history_enable(self):
return self.args is not None and \
not self.args.disable_history and \
self.get_items_history_list() is not None
not self.args.disable_history and \
self.get_items_history_list() is not None
def init_stats_history(self):
"""Init the stats history (dict of GlancesAttribute)."""
......@@ -326,7 +337,6 @@ class GlancesPlugin(object):
re.split(r"(\d+|\D+)", self.has_alias(stat[key]) or stat[key])
)))
@short_system_name.setter
def short_system_name(self, short_name):
"""Set the short detected OS name (SNMP)."""
......@@ -960,6 +970,83 @@ class GlancesPlugin(object):
"""Go to a new line."""
return self.curse_add_line('\n')
def curse_add_stat(self, key, width=None,
header='', separator='', trailer=''):
"""Return a list of dict messages with the 'key: value' result
<=== width ===>
__key : 80.5%__
| | | | |_ trailer
| | | |_ self.stats[key]
| | |_ separator
| |_ key
|_ trailer
Instead of:
msg = ' {:8}'.format('idle:')
ret.append(self.curse_add_line(msg, optional=self.get_views(key='idle', option='optional')))
msg = '{:5.1f}%'.format(self.stats['idle'])
ret.append(self.curse_add_line(msg, optional=self.get_views(key='idle', option='optional')))
Use:
ret.extend(self.curse_add_stat('idle', width=15, header=' '))
"""
# Check if a shortname is defined
if 'short_name' in self.fields_description[key]:
key_name = self.fields_description[key]['short_name']
else:
key_name = key
# Check if unit is defined and get the short unit char in the unit_sort dict
if 'unit' in self.fields_description[key] and self.fields_description[key]['unit'] in fields_unit_short:
# Get the shortname
unit_short = fields_unit_short[self.fields_description[key]['unit']]
else:
unit_short = ''
# Check if unit is defined and get the unit type unit_type dict
if 'unit' in self.fields_description[key] and self.fields_description[key]['unit'] in fields_unit_type:
# Get the shortname
unit_type = fields_unit_type[self.fields_description[key]['unit']]
else:
unit_type = 'float'
# Is it a rate ? Yes, compute it thanks to the time_since_update key
if 'rate' in self.fields_description[key] and self.fields_description[key]['rate'] is True:
value = self.stats[key] // self.stats['time_since_update']
else:
value = self.stats[key]
if width is None:
msg_item = header + '{}'.format(key_name) + separator
if unit_type == 'float':
msg_value = '{:.1f}{}'.format(value, unit_short) + trailer
elif 'min_symbol' in self.fields_description[key]:
msg_value = '{}{}'.format(self.auto_unit(int(value),
min_symbol=self.fields_description[key]['min_symbol']),
unit_short) + trailer
else:
msg_value = '{}{}'.format(int(value), unit_short) + trailer
else:
# Define the size of the message
# item will be on the left
# value will be on the right
msg_item = header + '{:{width}}'.format(key_name, width=width-7) + separator
if unit_type == 'float':
msg_value = '{:5.1f}{}'.format(value, unit_short) + trailer
elif 'min_symbol' in self.fields_description[key]:
msg_value = '{:>5}{}'.format(self.auto_unit(int(value),
min_symbol=self.fields_description[key]['min_symbol']),
unit_short) + trailer
else:
msg_value = '{:>5}{}'.format(int(value), unit_short) + trailer
decoration = self.get_views(key=key, option='decoration')
optional = self.get_views(key=key, option='optional')
return [self.curse_add_line(msg_item, optional=optional),
self.curse_add_line(msg_value, decoration=decoration, optional=optional)]
@property
def align(self):
"""Get the curse align."""
......@@ -1045,6 +1132,7 @@ class GlancesPlugin(object):
- if the plugin is enabled.
- if the refresh_timer is finished
"""
def wrapper(self, *args, **kw):
if self.is_enable() and (self.refresh_timer.finished() or self.stats == self.get_init_value):
# Run the method
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册