mirror of https://github.com/nicolargo/glances
Merge pull request #2919 from ariel-anieli/refactor-plugin-model-msg-curse
Refactorized `glances.plugins.containers.PluginModel.msg_curse()`pull/2924/head
commit
504cf0613f
|
@ -9,6 +9,7 @@
|
|||
"""Containers plugin."""
|
||||
|
||||
from copy import deepcopy
|
||||
from functools import partial, reduce
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
from glances.globals import iteritems, itervalues
|
||||
|
@ -290,17 +291,7 @@ class PluginModel(GlancesPluginModel):
|
|||
|
||||
return True
|
||||
|
||||
def msg_curse(self, args=None, max_width: Optional[int] = None) -> List[str]:
|
||||
"""Return the dict to display in the curse interface."""
|
||||
# Init the return message
|
||||
ret = []
|
||||
|
||||
# Only process if stats exist (and non null) and display plugin enable...
|
||||
if not self.stats or len(self.stats) == 0 or self.is_disabled():
|
||||
return ret
|
||||
|
||||
# Build the string message
|
||||
# Title
|
||||
def build_title(self, ret):
|
||||
msg = '{}'.format('CONTAINERS')
|
||||
ret.append(self.curse_add_line(msg, "TITLE"))
|
||||
msg = f' {len(self.stats)}'
|
||||
|
@ -311,72 +302,98 @@ class PluginModel(GlancesPluginModel):
|
|||
msg = f' (served by {self.stats[0].get("engine", "")})'
|
||||
ret.append(self.curse_add_line(msg))
|
||||
ret.append(self.curse_new_line())
|
||||
# Header
|
||||
ret.append(self.curse_new_line())
|
||||
# Get the maximum containers name
|
||||
# Max size is configurable. See feature request #1723.
|
||||
name_max_width = min(
|
||||
self.config.get_int_value('containers', 'max_name_size', default=20) if self.config is not None else 20,
|
||||
len(max(self.stats, key=lambda x: len(x['name']))['name']),
|
||||
)
|
||||
return ret
|
||||
|
||||
def maybe_add_engine_name_or_pod_line(self, ret):
|
||||
if self.views['show_engine_name']:
|
||||
msg = ' {:{width}}'.format('Engine', width=6)
|
||||
ret.append(self.curse_add_line(msg))
|
||||
ret = self.add_msg_to_line(ret, ' {:{width}}'.format('Engine', width=6))
|
||||
if self.views['show_pod_name']:
|
||||
msg = ' {:{width}}'.format('Pod', width=12)
|
||||
ret.append(self.curse_add_line(msg))
|
||||
msg = ' {:{width}}'.format('Name', width=name_max_width)
|
||||
ret.append(self.curse_add_line(msg, 'SORT' if self.sort_key == 'name' else 'DEFAULT'))
|
||||
msg = '{:>10}'.format('Status')
|
||||
ret.append(self.curse_add_line(msg))
|
||||
msg = '{:>10}'.format('Uptime')
|
||||
ret.append(self.curse_add_line(msg))
|
||||
msg = '{:>6}'.format('CPU%')
|
||||
ret.append(self.curse_add_line(msg, 'SORT' if self.sort_key == 'cpu_percent' else 'DEFAULT'))
|
||||
msg = '{:>7}'.format('MEM')
|
||||
ret.append(self.curse_add_line(msg, 'SORT' if self.sort_key == 'memory_usage' else 'DEFAULT'))
|
||||
msg = '/{:<7}'.format('MAX')
|
||||
ret.append(self.curse_add_line(msg))
|
||||
msg = '{:>7}'.format('IOR/s')
|
||||
ret.append(self.curse_add_line(msg))
|
||||
msg = ' {:<7}'.format('IOW/s')
|
||||
ret.append(self.curse_add_line(msg))
|
||||
msg = '{:>7}'.format('Rx/s')
|
||||
ret.append(self.curse_add_line(msg))
|
||||
msg = ' {:<7}'.format('Tx/s')
|
||||
ret.append(self.curse_add_line(msg))
|
||||
msg = ' {:8}'.format('Command')
|
||||
ret.append(self.curse_add_line(msg))
|
||||
ret = self.add_msg_to_line(ret, ' {:{width}}'.format('Pod', width=12))
|
||||
|
||||
# Data
|
||||
for container in self.stats:
|
||||
return ret
|
||||
|
||||
def maybe_add_engine_name_or_pod_name(self, ret, container):
|
||||
ret.append(self.curse_new_line())
|
||||
if self.views['show_engine_name']:
|
||||
ret.append(self.curse_add_line(' {:{width}}'.format(container["engine"], width=6)))
|
||||
if self.views['show_pod_name']:
|
||||
ret.append(self.curse_add_line(' {:{width}}'.format(container.get("pod_id", "-"), width=12)))
|
||||
# Name
|
||||
|
||||
return ret
|
||||
|
||||
def build_container_name(self, name_max_width):
|
||||
def build_for_this_max_length(ret, container):
|
||||
ret.append(
|
||||
self.curse_add_line(' {:{width}}'.format(container['name'][:name_max_width], width=name_max_width))
|
||||
)
|
||||
# Status
|
||||
|
||||
return ret
|
||||
|
||||
return build_for_this_max_length
|
||||
|
||||
def build_header(self, ret, name_max_width):
|
||||
ret.append(self.curse_new_line())
|
||||
|
||||
ret = self.maybe_add_engine_name_or_pod_line(ret)
|
||||
|
||||
msg = ' {:{width}}'.format('Name', width=name_max_width)
|
||||
ret.append(self.curse_add_line(msg, 'SORT' if self.sort_key == 'name' else 'DEFAULT'))
|
||||
|
||||
msgs = ['{:>10}'.format('Status'), '{:>10}'.format('Uptime')]
|
||||
ret = reduce(self.add_msg_to_line, msgs, ret)
|
||||
|
||||
msg = '{:>6}'.format('CPU%')
|
||||
ret.append(self.curse_add_line(msg, 'SORT' if self.sort_key == 'cpu_percent' else 'DEFAULT'))
|
||||
msg = '{:>7}'.format('MEM')
|
||||
ret.append(self.curse_add_line(msg, 'SORT' if self.sort_key == 'memory_usage' else 'DEFAULT'))
|
||||
|
||||
msgs = [
|
||||
'/{:<7}'.format('MAX'),
|
||||
'{:>7}'.format('IOR/s'),
|
||||
' {:<7}'.format('IOW/s'),
|
||||
'{:>7}'.format('Rx/s'),
|
||||
' {:<7}'.format('Tx/s'),
|
||||
' {:8}'.format('Command'),
|
||||
]
|
||||
|
||||
return reduce(self.add_msg_to_line, msgs, ret)
|
||||
|
||||
def add_msg_to_line(self, ret, msg):
|
||||
ret.append(self.curse_add_line(msg))
|
||||
|
||||
return ret
|
||||
|
||||
def get_max_of_container_names(self):
|
||||
return min(
|
||||
self.config.get_int_value('containers', 'max_name_size', default=20) if self.config is not None else 20,
|
||||
len(max(self.stats, key=lambda x: len(x['name']))['name']),
|
||||
)
|
||||
|
||||
def build_status_name(self, ret, container):
|
||||
status = self.container_alert(container['status'])
|
||||
msg = '{:>10}'.format(container['status'][0:10])
|
||||
ret.append(self.curse_add_line(msg, status))
|
||||
# Uptime
|
||||
|
||||
return ret
|
||||
|
||||
def build_uptime_line(self, ret, container):
|
||||
if container['uptime']:
|
||||
msg = '{:>10}'.format(container['uptime'])
|
||||
else:
|
||||
msg = '{:>10}'.format('_')
|
||||
ret.append(self.curse_add_line(msg))
|
||||
# CPU
|
||||
|
||||
return self.add_msg_to_line(ret, msg)
|
||||
|
||||
def build_cpu_line(self, ret, container):
|
||||
try:
|
||||
msg = '{:>6.1f}'.format(container['cpu']['total'])
|
||||
except (KeyError, TypeError):
|
||||
msg = '{:>6}'.format('_')
|
||||
ret.append(self.curse_add_line(msg, self.get_views(item=container['name'], key='cpu', option='decoration')))
|
||||
# MEM
|
||||
|
||||
return ret
|
||||
|
||||
def build_memory_line(self, ret, container):
|
||||
try:
|
||||
msg = '{:>7}'.format(self.auto_unit(self.memory_usage_no_cache(container['memory'])))
|
||||
except KeyError:
|
||||
|
@ -387,7 +404,10 @@ class PluginModel(GlancesPluginModel):
|
|||
except (KeyError, TypeError):
|
||||
msg = '/{:<7}'.format('_')
|
||||
ret.append(self.curse_add_line(msg))
|
||||
# IO R/W
|
||||
|
||||
return ret
|
||||
|
||||
def build_io_line(self, ret, container):
|
||||
unit = 'B'
|
||||
try:
|
||||
value = self.auto_unit(int(container['io_rx'])) + unit
|
||||
|
@ -401,7 +421,11 @@ class PluginModel(GlancesPluginModel):
|
|||
except (KeyError, TypeError):
|
||||
msg = ' {:<7}'.format('_')
|
||||
ret.append(self.curse_add_line(msg))
|
||||
# NET RX/TX
|
||||
|
||||
return ret
|
||||
|
||||
def build_net_line(self, args):
|
||||
def build_with_this_args(ret, container):
|
||||
if args.byte:
|
||||
# Bytes per second (for dummy)
|
||||
to_bit = 1
|
||||
|
@ -422,7 +446,12 @@ class PluginModel(GlancesPluginModel):
|
|||
except (KeyError, TypeError):
|
||||
msg = ' {:<7}'.format('_')
|
||||
ret.append(self.curse_add_line(msg))
|
||||
# Command
|
||||
|
||||
return ret
|
||||
|
||||
return build_with_this_args
|
||||
|
||||
def build_cmd_line(self, ret, container):
|
||||
if container['command'] is not None:
|
||||
msg = ' {}'.format(container['command'])
|
||||
else:
|
||||
|
@ -431,6 +460,54 @@ class PluginModel(GlancesPluginModel):
|
|||
|
||||
return ret
|
||||
|
||||
def msg_curse(self, args=None, max_width: Optional[int] = None) -> List[str]:
|
||||
"""Return the dict to display in the curse interface."""
|
||||
# Init the return message
|
||||
init = []
|
||||
|
||||
# Only process if stats exist (and non null) and display plugin enable...
|
||||
conditions = [not self.stats, len(self.stats) == 0, self.is_disabled()]
|
||||
if any(conditions):
|
||||
return init
|
||||
|
||||
# Build the string message
|
||||
# Get the maximum containers name
|
||||
# Max size is configurable. See feature request #1723.
|
||||
name_max_width = self.get_max_of_container_names()
|
||||
|
||||
steps = [
|
||||
self.build_title,
|
||||
partial(self.build_header, name_max_width=name_max_width),
|
||||
self.build_data_line(name_max_width, args),
|
||||
]
|
||||
|
||||
return reduce(lambda ret, step: step(ret), steps, init)
|
||||
|
||||
def build_data_line(self, name_max_width, args):
|
||||
def build_for_this_params(ret):
|
||||
build_data_with_params = self.build_container_data(name_max_width, args)
|
||||
return reduce(build_data_with_params, self.stats, ret)
|
||||
|
||||
return build_for_this_params
|
||||
|
||||
def build_container_data(self, name_max_width, args):
|
||||
def build_with_this_params(ret, container):
|
||||
steps = [
|
||||
self.maybe_add_engine_name_or_pod_name,
|
||||
self.build_container_name(name_max_width),
|
||||
self.build_status_name,
|
||||
self.build_uptime_line,
|
||||
self.build_cpu_line,
|
||||
self.build_memory_line,
|
||||
self.build_io_line,
|
||||
self.build_net_line(args),
|
||||
self.build_cmd_line,
|
||||
]
|
||||
|
||||
return reduce(lambda ret, step: step(ret, container), steps, ret)
|
||||
|
||||
return build_with_this_params
|
||||
|
||||
@staticmethod
|
||||
def container_alert(status: str) -> str:
|
||||
"""Analyse the container status.
|
||||
|
|
Loading…
Reference in New Issue