diff options
author | nicolargo <nicolas@nicolargo.com> | 2017-04-03 10:20:11 +0200 |
---|---|---|
committer | nicolargo <nicolas@nicolargo.com> | 2017-04-03 10:20:11 +0200 |
commit | 9b71b377d8fe8e0f1ff8f7c7f07d9361e489dd90 (patch) | |
tree | 32285eba372c2c3eca06f04282b6af7f1ebdcf89 | |
parent | 130cd2961a5a83c2f8735dc637a5a2d37b25c4a5 (diff) | |
parent | 6058ee2fca05469d3a6fe4abe3b0e5dfb681a89c (diff) |
Merge branch 'issue1077' into develop
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | docs/_static/trend.png | bin | 0 -> 23021 bytes | |||
-rw-r--r-- | docs/aoa/cpu.rst | 6 | ||||
-rw-r--r-- | docs/aoa/memory.rst | 6 | ||||
-rw-r--r-- | docs/man/glances.1 | 2 | ||||
-rw-r--r-- | glances/attribute.py | 4 | ||||
-rw-r--r-- | glances/compat.py | 4 | ||||
-rw-r--r-- | glances/history.py | 4 | ||||
-rw-r--r-- | glances/plugins/glances_cpu.py | 10 | ||||
-rw-r--r-- | glances/plugins/glances_mem.py | 4 | ||||
-rw-r--r-- | glances/plugins/glances_memswap.py | 4 | ||||
-rw-r--r-- | glances/plugins/glances_plugin.py | 32 |
12 files changed, 67 insertions, 10 deletions
@@ -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: diff --git a/docs/_static/trend.png b/docs/_static/trend.png Binary files differnew file mode 100644 index 00000000..7cf0cff4 --- /dev/null +++ b/docs/_static/trend.png diff --git a/docs/aoa/cpu.rst b/docs/aoa/cpu.rst index ead6a0df..8f531bb7 100644 --- a/docs/aoa/cpu.rst +++ b/docs/aoa/cpu.rst @@ -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 diff --git a/docs/aoa/memory.rst b/docs/aoa/memory.rst index 0cd6afc8..37795cb5 100644 --- a/docs/aoa/memory.rst +++ b/docs/aoa/memory.rst @@ -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 diff --git a/docs/man/glances.1 b/docs/man/glances.1 index 1f0b9fb2..404327e1 100644 --- a/docs/man/glances.1 +++ b/docs/man/glances.1 @@ -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 . diff --git a/glances/attribute.py b/glances/attribute.py index 5f008650..41b9c8b0 100644 --- a/glances/attribute.py +++ b/glances/attribute.py @@ -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:]] diff --git a/glances/compat.py b/glances/compat.py index bfec1433..ad28709c 100644 --- a/glances/compat.py +++ b/glances/compat.py @@ -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)""" diff --git a/glances/history.py b/glances/history.py index ff222328..433f15df 100644 --- a/glances/history.py +++ b/glances/history.py @@ -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)""" diff --git a/glances/plugins/glances_cpu.py b/glances/plugins/glances_cpu.py index 6dee43c0..c9ce5501 100644 --- a/glances/plugins/glances_cpu.py +++ b/glances/plugins/glances_cpu.py @@ -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: diff --git a/glances/plugins/glances_mem.py b/glances/plugins/glances_mem.py index 3cbfc2a4..eaebfa97 100644 --- a/glances/plugins/glances_mem.py +++ b/glances/plugins/glances_mem.py @@ -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)) diff --git a/glances/plugins/glances_memswap.py b/glances/plugins/glances_memswap.py index eedd0eaa..ec8f7bee 100644 --- a/glances/plugins/glances_memswap.py +++ b/glances/plugins/glances_memswap.py @@ -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)) diff --git a/glances/plugins/glances_plugin.py b/glances/plugins/glances_plugin.py index 48cc7cd3..f0dd1cac 100644 --- a/glances/plugins/glances_plugin.py +++ b/glances/plugins/glances_plugin.py @@ -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): |