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:
|
Enhancements and new features:
|
||||||
|
|
||||||
* Use -> and <- arrows keys to switch between processing sort (issue #1075)
|
* Use -> and <- arrows keys to switch between processing sort (issue #1075)
|
||||||
|
* Add trends in the Curses interface (issue #1077)
|
||||||
|
|
||||||
Bugs corrected:
|
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::
|
.. note::
|
||||||
Limit values can be overwritten in the configuration file under
|
Limit values can be overwritten in the configuration file under
|
||||||
the ``[cpu]`` and/or ``[percpu]`` sections.
|
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::
|
.. note::
|
||||||
Limit values can be overwritten in the configuration file under
|
Limit values can be overwritten in the configuration file under
|
||||||
the ``[memory]`` and/or ``[memswap]`` sections.
|
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.
|
.\" 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
|
.SH NAME
|
||||||
glances \- An eye on your system
|
glances \- An eye on your system
|
||||||
.
|
.
|
||||||
|
@ -126,6 +126,10 @@ class GlancesAttribute(object):
|
|||||||
"""
|
"""
|
||||||
return self._history[-pos]
|
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):
|
def history_json(self, nb=0):
|
||||||
"""Return the history of last nb items (0 for all) In ISO JSON format"""
|
"""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:]]
|
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 xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
from urllib.error import HTTPError, URLError
|
from urllib.error import HTTPError, URLError
|
||||||
|
from statistics import mean
|
||||||
|
|
||||||
input = input
|
input = input
|
||||||
range = range
|
range = range
|
||||||
@ -103,6 +104,9 @@ else:
|
|||||||
viewvalues = operator.methodcaller('viewvalues')
|
viewvalues = operator.methodcaller('viewvalues')
|
||||||
viewitems = operator.methodcaller('viewitems')
|
viewitems = operator.methodcaller('viewitems')
|
||||||
|
|
||||||
|
def mean(numbers):
|
||||||
|
return float(sum(numbers)) / max(len(numbers), 1)
|
||||||
|
|
||||||
def to_ascii(s):
|
def to_ascii(s):
|
||||||
"""Convert the unicode 's' to a ASCII string
|
"""Convert the unicode 's' to a ASCII string
|
||||||
Usefull to remove accent (diacritics)"""
|
Usefull to remove accent (diacritics)"""
|
||||||
|
@ -49,9 +49,9 @@ class GlancesHistory(object):
|
|||||||
for a in self.stats_history:
|
for a in self.stats_history:
|
||||||
self.stats_history[a].history_reset()
|
self.stats_history[a].history_reset()
|
||||||
|
|
||||||
def get(self):
|
def get(self, nb=0):
|
||||||
"""Get the history as a dict of list"""
|
"""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):
|
def get_json(self, nb=0):
|
||||||
"""Get the history as a dict of list (with list JSON compliant)"""
|
"""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
|
idle_tag = 'user' not in self.stats
|
||||||
|
|
||||||
# Header
|
# Header
|
||||||
msg = '{:8}'.format('CPU')
|
msg = '{}'.format('CPU')
|
||||||
ret.append(self.curse_add_line(msg, "TITLE"))
|
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
|
# Total CPU usage
|
||||||
msg = '{:5.1f}%'.format(self.stats['total'])
|
msg = '{:5.1f}%'.format(self.stats['total'])
|
||||||
if idle_tag:
|
if idle_tag:
|
||||||
|
@ -183,8 +183,10 @@ class Plugin(GlancesPlugin):
|
|||||||
|
|
||||||
# Build the string message
|
# Build the string message
|
||||||
# Header
|
# Header
|
||||||
msg = '{:5} '.format('MEM')
|
msg = '{}'.format('MEM')
|
||||||
ret.append(self.curse_add_line(msg, "TITLE"))
|
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
|
# Percent memory usage
|
||||||
msg = '{:>7.1%}'.format(self.stats['percent'] / 100)
|
msg = '{:>7.1%}'.format(self.stats['percent'] / 100)
|
||||||
ret.append(self.curse_add_line(msg))
|
ret.append(self.curse_add_line(msg))
|
||||||
|
@ -154,8 +154,10 @@ class Plugin(GlancesPlugin):
|
|||||||
|
|
||||||
# Build the string message
|
# Build the string message
|
||||||
# Header
|
# Header
|
||||||
msg = '{:7} '.format('SWAP')
|
msg = '{}'.format('SWAP')
|
||||||
ret.append(self.curse_add_line(msg, "TITLE"))
|
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
|
# Percent memory usage
|
||||||
msg = '{:>6.1%}'.format(self.stats['percent'] / 100)
|
msg = '{:>6.1%}'.format(self.stats['percent'] / 100)
|
||||||
ret.append(self.curse_add_line(msg))
|
ret.append(self.curse_add_line(msg))
|
||||||
|
@ -27,7 +27,7 @@ import re
|
|||||||
import json
|
import json
|
||||||
from operator import itemgetter
|
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.actions import GlancesActions
|
||||||
from glances.history import GlancesHistory
|
from glances.history import GlancesHistory
|
||||||
from glances.logger import logger
|
from glances.logger import logger
|
||||||
@ -156,12 +156,13 @@ class GlancesPlugin(object):
|
|||||||
"""Return the items history list."""
|
"""Return the items history list."""
|
||||||
return self.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
|
"""Return
|
||||||
- the stats history (dict of list) if item is None
|
- the stats history (dict of list) if item is None
|
||||||
- the stats history for the given item (list) instead
|
- the stats history for the given item (list) instead
|
||||||
- None if item did not exist in the history"""
|
- None if item did not exist in the history
|
||||||
s = self.stats_history.get()
|
Limit to lasts nb items (all if nb=0)"""
|
||||||
|
s = self.stats_history.get(nb=nb)
|
||||||
if item is None:
|
if item is None:
|
||||||
return s
|
return s
|
||||||
else:
|
else:
|
||||||
@ -215,6 +216,17 @@ class GlancesPlugin(object):
|
|||||||
else:
|
else:
|
||||||
return None
|
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
|
@property
|
||||||
def input_method(self):
|
def input_method(self):
|
||||||
"""Get the input method."""
|
"""Get the input method."""
|
||||||
@ -798,6 +810,18 @@ class GlancesPlugin(object):
|
|||||||
value, decimal=decimal_precision, symbol=symbol)
|
value, decimal=decimal_precision, symbol=symbol)
|
||||||
return '{!s}'.format(number)
|
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):
|
def _check_decorator(fct):
|
||||||
"""Check if the plugin is enabled."""
|
"""Check if the plugin is enabled."""
|
||||||
def wrapper(self, *args, **kw):
|
def wrapper(self, *args, **kw):
|
||||||
|
Loading…
Reference in New Issue
Block a user