summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--glances/core/glances_server.py6
-rw-r--r--glances/core/glances_stats.py11
-rw-r--r--glances/outputs/glances_bottle.py52
-rw-r--r--glances/plugins/glances_diskio.py2
-rw-r--r--glances/plugins/glances_fs.py2
-rw-r--r--glances/plugins/glances_network.py2
-rw-r--r--glances/plugins/glances_raid.py3
-rw-r--r--glances/plugins/glances_sensors.py11
-rwxr-xr-xunitest-restful.py39
-rwxr-xr-xunitest-xmlrpc.py30
11 files changed, 136 insertions, 23 deletions
diff --git a/NEWS b/NEWS
index b2c1d556..4c75b902 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,7 @@ Enhancements and news features:
* Add the Docker plugin (issue #440)
* It is possible, through the configuration file, to define if an alarm should be logged or not (using the _log option) (issue #437)
* You can now set alarm for Disk IO
+ * API: add getAllLimits and getAllViews methods (issue#481)
Bugs corrected:
diff --git a/glances/core/glances_server.py b/glances/core/glances_server.py
index 91d627bb..6cf8176a 100644
--- a/glances/core/glances_server.py
+++ b/glances/core/glances_server.py
@@ -160,7 +160,11 @@ class GlancesInstance(object):
def getAllLimits(self):
# Return all the plugins limits
- return json.dumps(self.stats.getAllLimits())
+ return json.dumps(self.stats.getAllLimitsAsDict())
+
+ def getAllViews(self):
+ # Return all the plugins views
+ return json.dumps(self.stats.getAllViewsAsDict())
def getAllMonitored(self):
# Return the processes monitored list
diff --git a/glances/core/glances_stats.py b/glances/core/glances_stats.py
index 859dc0f9..8b92334f 100644
--- a/glances/core/glances_stats.py
+++ b/glances/core/glances_stats.py
@@ -190,6 +190,17 @@ class GlancesStats(object):
ret[p] = self._plugins[p].get_limits()
return ret
+ def getAllViews(self):
+ """Return the plugins views"""
+ return [self._plugins[p].get_views() for p in self._plugins]
+
+ def getAllViewsAsDict(self):
+ """Return all the stats views (dict)"""
+ ret = {}
+ for p in self._plugins:
+ ret[p] = self._plugins[p].get_views()
+ return ret
+
def get_plugin_list(self):
"""Return the plugin list."""
self._plugins
diff --git a/glances/outputs/glances_bottle.py b/glances/outputs/glances_bottle.py
index dded2b54..4256efd1 100644
--- a/glances/outputs/glances_bottle.py
+++ b/glances/outputs/glances_bottle.py
@@ -70,8 +70,10 @@ class GlancesBottle(object):
self._app.route('/api/2/pluginslist', method="GET", callback=self._api_plugins)
self._app.route('/api/2/all', method="GET", callback=self._api_all)
self._app.route('/api/2/all/limits', method="GET", callback=self._api_all_limits)
+ self._app.route('/api/2/all/views', method="GET", callback=self._api_all_views)
self._app.route('/api/2/:plugin', method="GET", callback=self._api)
self._app.route('/api/2/:plugin/limits', method="GET", callback=self._api_limits)
+ self._app.route('/api/2/:plugin/views', method="GET", callback=self._api_views)
self._app.route('/api/2/:plugin/:item', method="GET", callback=self._api_item)
self._app.route('/api/2/:plugin/:item/:value', method="GET", callback=self._api_value)
@@ -151,7 +153,7 @@ class GlancesBottle(object):
self.stats.update()
try:
- # Get the JSON value of the stat ID
+ # Get the JSON value of the stat value
statval = json.dumps(self.stats.getAllAsDict())
except Exception as e:
abort(404, "Cannot get stats (%s)" % str(e))
@@ -168,12 +170,29 @@ class GlancesBottle(object):
response.content_type = 'application/json'
try:
- # Get the JSON value of the stat ID
+ # Get the JSON value of the stat limits
limits = json.dumps(self.stats.getAllLimitsAsDict())
except Exception as e:
abort(404, "Cannot get limits (%s)" % (str(e)))
return limits
+ def _api_all_views(self):
+ """
+ Glances API RESTFul implementation
+ Return the JSON representation of all the plugins views
+ HTTP/200 if OK
+ HTTP/400 if plugin is not found
+ HTTP/404 if others error
+ """
+ response.content_type = 'application/json'
+
+ try:
+ # Get the JSON value of the stat view
+ limits = json.dumps(self.stats.getAllViewsAsDict())
+ except Exception as e:
+ abort(404, "Cannot get views (%s)" % (str(e)))
+ return limits
+
def _api(self, plugin):
"""
Glances API RESTFul implementation
@@ -214,11 +233,34 @@ class GlancesBottle(object):
# self.stats.update()
try:
- # Get the JSON value of the stat ID
- limits = self.stats.get_plugin(plugin).get_limits()
+ # Get the JSON value of the stat limits
+ ret = self.stats.get_plugin(plugin).get_limits()
except Exception as e:
abort(404, "Cannot get limits for plugin %s (%s)" % (plugin, str(e)))
- return limits
+ return ret
+
+ def _api_views(self, plugin):
+ """
+ Glances API RESTFul implementation
+ Return the JSON views of a given plugin
+ HTTP/200 if OK
+ HTTP/400 if plugin is not found
+ HTTP/404 if others error
+ """
+ response.content_type = 'application/json'
+
+ if plugin not in self.plugins_list:
+ abort(400, "Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list))
+
+ # Update the stat
+ # self.stats.update()
+
+ try:
+ # Get the JSON value of the stat views
+ ret = self.stats.get_plugin(plugin).get_views()
+ except Exception as e:
+ abort(404, "Cannot get views for plugin %s (%s)" % (plugin, str(e)))
+ return ret
def _api_item(self, plugin, item):
"""
diff --git a/glances/plugins/glances_diskio.py b/glances/plugins/glances_diskio.py
index 6404aa24..e0ee3cb5 100644
--- a/glances/plugins/glances_diskio.py
+++ b/glances/plugins/glances_diskio.py
@@ -134,7 +134,7 @@ class Plugin(GlancesPlugin):
# Add specifics informations
# Alert
- for i in sorted(self.stats, key=operator.itemgetter(self.get_key())):
+ for i in self.stats:
disk_real_name = i['disk_name']
self.views[i[self.get_key()]]['read_bytes']['decoration'] = self.get_alert(int(i['read_bytes'] // i['time_since_update']),
header=disk_real_name + '_rx')
diff --git a/glances/plugins/glances_fs.py b/glances/plugins/glances_fs.py
index ac2df401..e4dfbcff 100644
--- a/glances/plugins/glances_fs.py
+++ b/glances/plugins/glances_fs.py
@@ -180,7 +180,7 @@ class Plugin(GlancesPlugin):
# Add specifics informations
# Alert
- for i in sorted(self.stats, key=operator.itemgetter(self.get_key())):
+ for i in self.stats:
self.views[i[self.get_key()]]['used']['decoration'] = self.get_alert(i['used'], max=i['size'], header=i['mnt_point'])
def msg_curse(self, args=None, max_width=None):
diff --git a/glances/plugins/glances_network.py b/glances/plugins/glances_network.py
index 0083f198..0f311015 100644
--- a/glances/plugins/glances_network.py
+++ b/glances/plugins/glances_network.py
@@ -195,7 +195,7 @@ class Plugin(GlancesPlugin):
# Add specifics informations
# Alert
- for i in sorted(self.stats, key=operator.itemgetter(self.get_key())):
+ for i in self.stats:
ifrealname = i['interface_name'].split(':')[0]
self.views[i[self.get_key()]]['rx']['decoration'] = self.get_alert(int(i['rx'] // i['time_since_update'] * 8),
header=ifrealname + '_rx')
diff --git a/glances/plugins/glances_raid.py b/glances/plugins/glances_raid.py
index 20743c36..a31baccf 100644
--- a/glances/plugins/glances_raid.py
+++ b/glances/plugins/glances_raid.py
@@ -72,6 +72,9 @@ class Plugin(GlancesPlugin):
# No standard way for the moment...
pass
+ # Update the view
+ self.update_views()
+
return self.stats
def msg_curse(self, args=None):
diff --git a/glances/plugins/glances_sensors.py b/glances/plugins/glances_sensors.py
index 9cbae8b8..526d0980 100644
--- a/glances/plugins/glances_sensors.py
+++ b/glances/plugins/glances_sensors.py
@@ -172,13 +172,10 @@ class Plugin(GlancesPlugin):
msg = '{0:18}'.format(label)
ret.append(self.curse_add_line(msg))
msg = '{0:>5}'.format(i['value'])
- try:
- ret.append(self.curse_add_line(
- msg, self.get_views(item=i[self.get_key()],
- key='value',
- option='decoration')))
- except TypeError:
- pass
+ ret.append(self.curse_add_line(
+ msg, self.get_views(item=i[self.get_key()],
+ key='value',
+ option='decoration')))
return ret
diff --git a/unitest-restful.py b/unitest-restful.py
index 9b154e34..55fb5292 100755
--- a/unitest-restful.py
+++ b/unitest-restful.py
@@ -124,8 +124,6 @@ class TestGlances(unittest.TestCase):
plist = requests.get("%s/%s" % (URL, method))
- print(plist.json())
-
for p in plist.json():
print("HTTP RESTFul request: %s/%s" % (URL, p))
req = requests.get("%s/%s" % (URL, p))
@@ -175,6 +173,43 @@ class TestGlances(unittest.TestCase):
self.assertTrue(req.ok)
self.assertIsInstance(req.json(), types.DictType)
+ def test_007_all_views(self):
+ """All"""
+ method = "all/views"
+ print('INFO: [TEST_007] Get all views')
+
+ print("HTTP RESTFul request: %s/%s" % (URL, method))
+ req = requests.get("%s/%s" % (URL, method))
+
+ self.assertTrue(req.ok)
+ self.assertIsInstance(req.json(), types.DictType)
+
+ def test_008_plugins_limits(self):
+ """Plugins limits"""
+ method = "pluginslist"
+ print('INFO: [TEST_008] Plugins limits')
+
+ plist = requests.get("%s/%s" % (URL, method))
+
+ for p in plist.json():
+ print("HTTP RESTFul request: %s/%s/limits" % (URL, p))
+ req = requests.get("%s/%s/limits" % (URL, p))
+ self.assertTrue(req.ok)
+ self.assertIsInstance(req.json(), types.DictType)
+
+ def test_009_plugins_views(self):
+ """Plugins views"""
+ method = "pluginslist"
+ print('INFO: [TEST_009] Plugins views')
+
+ plist = requests.get("%s/%s" % (URL, method))
+
+ for p in plist.json():
+ print("HTTP RESTFul request: %s/%s/views" % (URL, p))
+ req = requests.get("%s/%s/views" % (URL, p))
+ self.assertTrue(req.ok)
+ self.assertIsInstance(req.json(), types.DictType)
+
def test_999_stop_server(self):
"""Stop the Glances Web Server"""
print('INFO: [TEST_999] Stop the Glances Web Server')
diff --git a/unitest-xmlrpc.py b/unitest-xmlrpc.py
index 4d14ce13..4e7a86bb 100755
--- a/unitest-xmlrpc.py
+++ b/unitest-xmlrpc.py
@@ -31,7 +31,7 @@ import json
import types
try:
from xmlrpc.client import ServerProxy
-except ImportError:
+except ImportError:
# Python 2
from xmlrpclib import ServerProxy
@@ -50,7 +50,8 @@ pid = None
# Unitary test is only available from a GNU/Linus machine
if not is_linux:
- print('ERROR: XML/RPC API unitaries tests should be ran on GNU/Linux operating system')
+ print(
+ 'ERROR: XML/RPC API unitaries tests should be ran on GNU/Linux operating system')
sys.exit(2)
else:
print('Unitary tests for {0} {1}'.format(appname, version))
@@ -77,6 +78,7 @@ client = ServerProxy(URL)
# Unitest class
# ==============
+
class TestGlances(unittest.TestCase):
"""Test Glances class."""
@@ -88,16 +90,16 @@ class TestGlances(unittest.TestCase):
def test_000_start_server(self):
"""Start the Glances Web Server"""
print('INFO: [TEST_000] Start the Glances Web Server')
-
+
global pid
-
+
cmdline = "/usr/bin/python -m glances -s -p %s" % SERVER_PORT
print("Run the Glances Server on port %s" % SERVER_PORT)
args = shlex.split(cmdline)
pid = subprocess.Popen(args)
print("Please wait...")
time.sleep(1)
-
+
self.assertTrue(pid is not None)
def test_001_all(self):
@@ -195,6 +197,24 @@ class TestGlances(unittest.TestCase):
req = json.loads(client.getProcessList())
self.assertIsInstance(req, types.ListType)
+ def test_010_all_limits(self):
+ """All limits"""
+ method = "getAllLimits()"
+ print('INFO: [TEST_010] Method: %s' % method)
+
+ req = json.loads(client.getAllLimits())
+ self.assertIsInstance(req, types.DictType)
+ self.assertIsInstance(req['cpu'], types.DictType)
+
+ def test_011_all_views(self):
+ """All views"""
+ method = "getAllViews()"
+ print('INFO: [TEST_011] Method: %s' % method)
+
+ req = json.loads(client.getAllViews())
+ self.assertIsInstance(req, types.DictType)
+ self.assertIsInstance(req['cpu'], types.DictType)
+
def test_999_stop_server(self):
"""Stop the Glances Web Server"""
print('INFO: [TEST_999] Stop the Glances Server')