mirror of
https://github.com/nicolargo/glances.git
synced 2024-11-28 05:42:57 +03:00
Merge branch 'issue1077' into develop
This commit is contained in:
commit
9b71b377d8
1
NEWS
1
NEWS
@ -8,6 +8,7 @@ Version 2.9.2
|
||||
Enhancements and new features:
|
||||
|
||||
* Use -> and <- arrows keys to switch between processing sort (issue #1075)
|
||||
* Add trends in the Curses interface (issue #1077)
|
||||
|
||||
Bugs corrected:
|
||||
|
||||
|
BIN
docs/_static/trend.png
vendored
Normal file
BIN
docs/_static/trend.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
@ -69,3 +69,9 @@ CPU (user/system) Status
|
||||
.. note::
|
||||
Limit values can be overwritten in the configuration file under
|
||||
the ``[cpu]`` and/or ``[percpu]`` sections.
|
||||
|
||||
.. note::
|
||||
A trend character could be displayed just after the title.
|
||||
* '-': value is more or less equal to the mean of the lasts N values
|
||||
* '/': value is higher than the mean of the lasts N values
|
||||
* '/': value is lower than the mean of the lasts N values
|
||||
|
@ -28,3 +28,9 @@ RAM/Swap Status
|
||||
.. note::
|
||||
Limit values can be overwritten in the configuration file under
|
||||
the ``[memory]`` and/or ``[memswap]`` sections.
|
||||
|
||||
.. note::
|
||||
A trend character could be displayed just after the title.
|
||||
* '-': value is more or less equal to the mean of the lasts N values
|
||||
* '/': value is higher than the mean of the lasts N values
|
||||
* '/': value is lower than the mean of the lasts N values
|
||||
|
@ -1,6 +1,6 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "GLANCES" "1" "Mar 29, 2017" "2.9.1" "Glances"
|
||||
.TH "GLANCES" "1" "Apr 03, 2017" "2.9.2_DEVELOP" "Glances"
|
||||
.SH NAME
|
||||
glances \- An eye on your system
|
||||
.
|
||||
|
@ -126,6 +126,10 @@ class GlancesAttribute(object):
|
||||
"""
|
||||
return self._history[-pos]
|
||||
|
||||
def history_raw(self, nb=0):
|
||||
"""Return the history of last nb items (0 for all) In ISO JSON format"""
|
||||
return self._history[-nb:]
|
||||
|
||||
def history_json(self, nb=0):
|
||||
"""Return the history of last nb items (0 for all) In ISO JSON format"""
|
||||
return [(i[0].isoformat(), i[1]) for i in self._history[-nb:]]
|
||||
|
@ -35,6 +35,7 @@ if PY3:
|
||||
from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
|
||||
from urllib.request import urlopen
|
||||
from urllib.error import HTTPError, URLError
|
||||
from statistics import mean
|
||||
|
||||
input = input
|
||||
range = range
|
||||
@ -103,6 +104,9 @@ else:
|
||||
viewvalues = operator.methodcaller('viewvalues')
|
||||
viewitems = operator.methodcaller('viewitems')
|
||||
|
||||
def mean(numbers):
|
||||
return float(sum(numbers)) / max(len(numbers), 1)
|
||||
|
||||
def to_ascii(s):
|
||||
"""Convert the unicode 's' to a ASCII string
|
||||
Usefull to remove accent (diacritics)"""
|
||||
|
@ -49,9 +49,9 @@ class GlancesHistory(object):
|
||||
for a in self.stats_history:
|
||||
self.stats_history[a].history_reset()
|
||||
|
||||
def get(self):
|
||||
def get(self, nb=0):
|
||||
"""Get the history as a dict of list"""
|
||||
return {i: self.stats_history[i].history for i in self.stats_history}
|
||||
return {i: self.stats_history[i].history_raw(nb=nb) for i in self.stats_history}
|
||||
|
||||
def get_json(self, nb=0):
|
||||
"""Get the history as a dict of list (with list JSON compliant)"""
|
||||
|
@ -229,8 +229,16 @@ class Plugin(GlancesPlugin):
|
||||
idle_tag = 'user' not in self.stats
|
||||
|
||||
# Header
|
||||
msg = '{:8}'.format('CPU')
|
||||
msg = '{}'.format('CPU')
|
||||
ret.append(self.curse_add_line(msg, "TITLE"))
|
||||
trend_user = self.get_trend('user')
|
||||
trend_system = self.get_trend('system')
|
||||
if trend_user is None or trend_user is None:
|
||||
trend_cpu = None
|
||||
else:
|
||||
trend_cpu = trend_user + trend_system
|
||||
msg = ' {:4}'.format(self.trend_msg(trend_cpu))
|
||||
ret.append(self.curse_add_line(msg))
|
||||
# Total CPU usage
|
||||
msg = '{:5.1f}%'.format(self.stats['total'])
|
||||
if idle_tag:
|
||||
|
@ -183,8 +183,10 @@ class Plugin(GlancesPlugin):
|
||||
|
||||
# Build the string message
|
||||
# Header
|
||||
msg = '{:5} '.format('MEM')
|
||||
msg = '{}'.format('MEM')
|
||||
ret.append(self.curse_add_line(msg, "TITLE"))
|
||||
msg = ' {:2}'.format(self.trend_msg(self.get_trend('percent')))
|
||||
ret.append(self.curse_add_line(msg))
|
||||
# Percent memory usage
|
||||
msg = '{:>7.1%}'.format(self.stats['percent'] / 100)
|
||||
ret.append(self.curse_add_line(msg))
|
||||
|
@ -154,8 +154,10 @@ class Plugin(GlancesPlugin):
|
||||
|
||||
# Build the string message
|
||||
# Header
|
||||
msg = '{:7} '.format('SWAP')
|
||||
msg = '{}'.format('SWAP')
|
||||
ret.append(self.curse_add_line(msg, "TITLE"))
|
||||
msg = ' {:3}'.format(self.trend_msg(self.get_trend('percent')))
|
||||
ret.append(self.curse_add_line(msg))
|
||||
# Percent memory usage
|
||||
msg = '{:>6.1%}'.format(self.stats['percent'] / 100)
|
||||
ret.append(self.curse_add_line(msg))
|
||||
|
@ -27,7 +27,7 @@ import re
|
||||
import json
|
||||
from operator import itemgetter
|
||||
|
||||
from glances.compat import iterkeys, itervalues, listkeys, map
|
||||
from glances.compat import iterkeys, itervalues, listkeys, map, mean
|
||||
from glances.actions import GlancesActions
|
||||
from glances.history import GlancesHistory
|
||||
from glances.logger import logger
|
||||
@ -156,12 +156,13 @@ class GlancesPlugin(object):
|
||||
"""Return the items history list."""
|
||||
return self.items_history_list
|
||||
|
||||
def get_raw_history(self, item=None):
|
||||
def get_raw_history(self, item=None, nb=0):
|
||||
"""Return
|
||||
- the stats history (dict of list) if item is None
|
||||
- the stats history for the given item (list) instead
|
||||
- None if item did not exist in the history"""
|
||||
s = self.stats_history.get()
|
||||
- None if item did not exist in the history
|
||||
Limit to lasts nb items (all if nb=0)"""
|
||||
s = self.stats_history.get(nb=nb)
|
||||
if item is None:
|
||||
return s
|
||||
else:
|
||||
@ -215,6 +216,17 @@ class GlancesPlugin(object):
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_trend(self, item, nb=6):
|
||||
"""Get the trend regarding to the last nb values
|
||||
The trend is the diff between the mean of the last nb values
|
||||
and the current one.
|
||||
"""
|
||||
raw_history = self.get_raw_history(item=item, nb=nb)
|
||||
if raw_history is None or len(raw_history) < nb:
|
||||
return None
|
||||
last_nb = [v[1] for v in raw_history]
|
||||
return last_nb[-1] - mean(last_nb[:-1])
|
||||
|
||||
@property
|
||||
def input_method(self):
|
||||
"""Get the input method."""
|
||||
@ -798,6 +810,18 @@ class GlancesPlugin(object):
|
||||
value, decimal=decimal_precision, symbol=symbol)
|
||||
return '{!s}'.format(number)
|
||||
|
||||
def trend_msg(self, trend, significant=1):
|
||||
"""Return the trend message
|
||||
Do not take into account if trend < significant"""
|
||||
ret = '-'
|
||||
if trend is None:
|
||||
ret = ' '
|
||||
elif trend > significant:
|
||||
ret = '/'
|
||||
elif trend < -significant:
|
||||
ret = '\\'
|
||||
return ret
|
||||
|
||||
def _check_decorator(fct):
|
||||
"""Check if the plugin is enabled."""
|
||||
def wrapper(self, *args, **kw):
|
||||
|
Loading…
Reference in New Issue
Block a user