Limit number of item is configurable through the restfull API

pull/893/head
nicolargo 2016-05-30 15:56:22 +02:00
parent 8d7c8bbed2
commit 857ec54daa
5 changed files with 119 additions and 12 deletions

View File

@ -126,6 +126,10 @@ class GlancesAttribute(object):
"""
return self._history[-pos]
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:]]
def history_mean(self, nb=5):
"""Return the mean on the <nb> values in the history.
"""

View File

@ -96,7 +96,7 @@ class GlancesGraph(object):
index_all = 0
for p in stats.getAllPlugins():
# History
h = stats.get_plugin(p).get_stats_history()
h = stats.get_plugin(p).get_export_history()
# Current plugin item history list
ih = stats.get_plugin(p).get_items_history_list()
# Check if we must process history

View File

@ -52,3 +52,7 @@ class GlancesHistory(object):
def get(self):
"""Get the history as a dict of list"""
return {i: self.stats_history[i].history for i in self.stats_history}
def get_json(self, nb=0):
"""Get the history as a dict of list (with list JSON compliant)"""
return {i: self.stats_history[i].history_json(nb=nb) for i in self.stats_history}

View File

@ -90,9 +90,12 @@ class GlancesBottle(object):
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/history', method="GET", callback=self._api_history)
self._app.route('/api/2/:plugin/history/:nb', method="GET", callback=self._api_history)
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/history', method="GET", callback=self._api_item_history)
self._app.route('/api/2/:plugin/:item/:value', method="GET", callback=self._api_value)
def start(self, stats):
@ -287,6 +290,30 @@ class GlancesBottle(object):
abort(404, "Cannot get plugin %s (%s)" % (plugin, str(e)))
return statval
def _api_history(self, plugin, nb=0):
"""Glances API RESTFul implementation.
Return the JSON representation of a given plugin history
Limit to the last nb items (all if nb=0)
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 ID
statval = self.stats.get_plugin(plugin).get_stats_history(nb=int(nb))
except Exception as e:
abort(404, "Cannot get plugin history %s (%s)" % (plugin, str(e)))
return statval
def _api_limits(self, plugin):
"""Glances API RESTFul implementation.
@ -333,8 +360,8 @@ class GlancesBottle(object):
abort(404, "Cannot get views for plugin %s (%s)" % (plugin, str(e)))
return ret
def _api_itemvalue(self, plugin, item, value=None):
""" Father method for _api_item and _api_value"""
def _api_itemvalue(self, plugin, item, value=None, history=False):
"""Father method for _api_item and _api_value"""
response.content_type = 'application/json'
if plugin not in self.plugins_list:
@ -344,22 +371,28 @@ class GlancesBottle(object):
self.stats.update()
if value is None:
ret = self.stats.get_plugin(plugin).get_stats_item(item)
if history:
ret = self.stats.get_plugin(plugin).get_stats_history(item)
else:
ret = self.stats.get_plugin(plugin).get_stats_item(item)
if ret is None:
abort(404, "Cannot get item %s in plugin %s" % (item, plugin))
abort(404, "Cannot get item %s%s in plugin %s" % (item, 'history ' if history else '', plugin))
else:
ret = self.stats.get_plugin(plugin).get_stats_value(item, value)
if history:
ret = self.stats.get_plugin(plugin).get_stats_value_history(item, value)
else:
ret = self.stats.get_plugin(plugin).get_stats_value(item, value)
if ret is None:
abort(404, "Cannot get item(%s)=value(%s) in plugin %s" % (item, value, plugin))
abort(404, "Cannot get item %s(%s=%s) in plugin %s" % ('history ' if history else '', item, value, plugin))
return ret
def _api_item(self, plugin, item):
"""Glances API RESTFul implementation.
Return the JSON represenation of the couple plugin/item
Return the JSON representation of the couple plugin/item
HTTP/200 if OK
HTTP/400 if plugin is not found
HTTP/404 if others error
@ -367,6 +400,17 @@ class GlancesBottle(object):
"""
return self._api_itemvalue(plugin, item)
def _api_item_history(self, plugin, item):
"""Glances API RESTFul implementation.
Return the JSON representation of the couple plugin/history of item
HTTP/200 if OK
HTTP/400 if plugin is not found
HTTP/404 if others error
"""
return self._api_itemvalue(plugin, item, history=True)
def _api_value(self, plugin, item, value):
"""Glances API RESTFul implementation.

View File

@ -124,14 +124,69 @@ class GlancesPlugin(object):
description=i['description'],
history_max_size=None)
def get_stats_history(self):
"""Return the stats history (dict of list)."""
return self.stats_history.get()
def get_items_history_list(self):
"""Return the items history list."""
return self.items_history_list
def get_raw_history(self, item=None):
"""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()
if item is None:
return s
else:
if item in s:
return s[item]
else:
return None
def get_json_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
Limit to lasts nb items (all if nb=0)"""
s = self.stats_history.get_json(nb=nb)
if item is None:
return s
else:
if item in s:
return s[item]
else:
return None
def get_export_history(self, item=None):
"""Return the stats history object to export.
See get_raw_history for a full description"""
return self.get_raw_history(item=item)
def get_stats_history(self, item=None, nb=0):
"""Return the stats history as a JSON object (dict or None).
Limit to lasts nb items (all if nb=0)"""
s = self.get_json_history(nb=nb)
if item is None:
return json.dumps(s)
if isinstance(s, dict):
try:
return json.dumps({item: s[item]})
except KeyError as e:
logger.error("Cannot get item history {0} ({1})".format(item, e))
return None
elif isinstance(s, list):
try:
# Source:
# http://stackoverflow.com/questions/4573875/python-get-index-of-dictionary-item-in-list
return json.dumps({item: map(itemgetter(item), s)})
except (KeyError, ValueError) as e:
logger.error("Cannot get item history {0} ({1})".format(item, e))
return None
else:
return None
@property
def input_method(self):
"""Get the input method."""