On 04/24/2014 03:46 PM, Rodrigo Trujillo wrote:
On 04/22/2014 09:41 PM, Aline Manera wrote:
> From: Aline Manera <alinefm(a)br.ibm.com>
>
> GET /host/stats/history will return the host stats history - the last 60
> values.
> That way the grid in UI can show the history when displaying the host
> tab and then use /host/stats to get the new updated values - item by
> item.
>
> Signed-off-by: Aline Manera <alinefm(a)br.ibm.com>
> ---
> docs/API.md | 28 +++++++++++++++++++
> src/kimchi/control/host.py | 10 +++++++
> src/kimchi/mockmodel.py | 8 ++++++
> src/kimchi/model/host.py | 66
> ++++++++++++++++++++++++++++++--------------
> 4 files changed, 91 insertions(+), 21 deletions(-)
>
> diff --git a/docs/API.md b/docs/API.md
> index 716c983..1fd2c3c 100644
> --- a/docs/API.md
> +++ b/docs/API.md
> @@ -768,6 +768,34 @@ Contains the host sample data.
>
> *No actions defined*
>
> +### Resource: HostStatsHistory
> +
> +**URI:** /host/stats/history
> +
> +It is the sub-resource of Host Stats and the client uses it to get
> the host
> +stats history
> +
> +**Methods:**
> +
> +* **GET**: Retrieve host sample data history
> + * cpu_utilization: CPU utilization history
> + * memory: Memory statistics history
> + * total: Total amount of memory. The unit is Bytes.
> + * free: The amount of memory left unused by the system. The
> unit is Bytes.
> + * buffers: The amount of memory used for file buffers. The
> unit is Bytes.
> + * cached: The amount of memory used as cache memory. The
> unit is Bytes.
> + * avail: The total amount of buffer, cache and free memory.
> The unit is Bytes.
> + * disk_read_rate: IO throughput for reads history
> + * disk_write_rate: IO throughput for writes history
> + * net_sent_rate: Network throughput for writes history
> + * net_recv_rate: Network throughput for reads history
> +
> +* **POST**: *See HostStatsHistory Actions*
> +
> +**Actions (POST):**
> +
> +*No actions defined*
> +
> ### Collection: Plugins
>
> **URI:** /plugins
> diff --git a/src/kimchi/control/host.py b/src/kimchi/control/host.py
> index 003c4b9..ad34919 100644
> --- a/src/kimchi/control/host.py
> +++ b/src/kimchi/control/host.py
> @@ -56,6 +56,16 @@ class Host(Resource):
>
>
> class HostStats(Resource):
> + def __init__(self, model, id=None):
> + super(HostStats, self).__init__(model, id)
> + self.history = HostStatsHistory(self.model)
> +
> + @property
> + def data(self):
> + return self.info
> +
> +
> +class HostStatsHistory(Resource):
> @property
> def data(self):
> return self.info
> diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py
> index 866ad2c..ca1bea6 100644
> --- a/src/kimchi/mockmodel.py
> +++ b/src/kimchi/mockmodel.py
> @@ -810,6 +810,14 @@ class MockModel(object):
> 'net_recv_rate': round(random.uniform(0, 4000), 1),
> 'net_sent_rate': round(random.uniform(0, 4000), 1)}
>
> + def hoststatshistory_lookup(self, *name):
> + return {'cpu_utilization': random.sample(range(100), 30),
> + 'memory': random.sample(range(4000), 30),
> + 'disk_read_rate': random.sample(range(4000), 30),
> + 'disk_write_rate': random.sample(range(4000), 30),
> + 'net_recv_rate': random.sample(range(4000), 30),
> + 'net_sent_rate': random.sample(range(4000), 30)}
> +
> def users_get_list(self):
> return ["userA", "userB", "userC"]
>
> diff --git a/src/kimchi/model/host.py b/src/kimchi/model/host.py
> index e0ac760..3e2c827 100644
> --- a/src/kimchi/model/host.py
> +++ b/src/kimchi/model/host.py
> @@ -119,18 +119,18 @@ class HostStatsModel(object):
> __metaclass__ = Singleton
>
> def __init__(self, **kargs):
> - self.host_stats = defaultdict(int)
> + self.host_stats = defaultdict(list)
> self.host_stats_thread = BackgroundTask(HOST_STATS_INTERVAL,
> self._update_host_stats)
> self.host_stats_thread.start()
>
> def lookup(self, *name):
> - return {'cpu_utilization':
self.host_stats['cpu_utilization'],
> - 'memory': self.host_stats.get('memory'),
> - 'disk_read_rate':
self.host_stats['disk_read_rate'],
> - 'disk_write_rate':
self.host_stats['disk_write_rate'],
> - 'net_recv_rate': self.host_stats['net_recv_rate'],
> - 'net_sent_rate': self.host_stats['net_sent_rate']}
> + return {'cpu_utilization':
> self.host_stats['cpu_utilization'][-1],
> + 'memory': self.host_stats['memory'][-1],
> + 'disk_read_rate':
> self.host_stats['disk_read_rate'][-1],
> + 'disk_write_rate':
> self.host_stats['disk_write_rate'][-1],
> + 'net_recv_rate':
self.host_stats['net_recv_rate'][-1],
> + 'net_sent_rate':
self.host_stats['net_sent_rate'][-1]}
>
> def _update_host_stats(self):
> preTimeStamp = self.host_stats['timestamp']
> @@ -148,6 +148,12 @@ class HostStatsModel(object):
> self._get_percentage_host_cpu_usage()
> self._get_host_memory_stats()
>
> + # store only 60 stats (1 min)
> + for key, value in self.host_stats.iteritems():
> + if isinstance(value, list):
> + if len(value) == 60:
> + self.host_stats[key] = value[10:]
> +
> def _get_percentage_host_cpu_usage(self):
> # This is cpu usage producer. This producer will calculate
> the usage
> # at an interval of HOST_STATS_INTERVAL.
> @@ -155,7 +161,7 @@ class HostStatsModel(object):
> # psutil.cpu_percent maintains a cpu time sample.
> # It will update the cpu time sample when it is called.
> # So only this producer can call psutil.cpu_percent in kimchi.
> - self.host_stats['cpu_utilization'] = psutil.cpu_percent(None)
> + self.host_stats['cpu_utilization'].append(psutil.cpu_percent(None))
>
> def _get_host_memory_stats(self):
> virt_mem = psutil.virtual_memory()
> @@ -169,11 +175,13 @@ class HostStatsModel(object):
> 'cached': virt_mem.cached,
> 'buffers': virt_mem.buffers,
> 'avail': virt_mem.available}
> - self.host_stats['memory'] = memory_stats
> + self.host_stats['memory'].append(memory_stats)
>
> def _get_host_disk_io_rate(self, seconds):
> - prev_read_bytes = self.host_stats['disk_read_bytes']
> - prev_write_bytes = self.host_stats['disk_write_bytes']
> + disk_read_bytes = self.host_stats['disk_read_bytes']
> + disk_write_bytes = self.host_stats['disk_write_bytes']
> + prev_read_bytes = disk_read_bytes[-1] if disk_read_bytes else 0
> + prev_write_bytes = disk_write_bytes[-1] if disk_write_bytes
> else 0
>
> disk_io = psutil.disk_io_counters(False)
> read_bytes = disk_io.read_bytes
> @@ -182,14 +190,16 @@ class HostStatsModel(object):
> rd_rate = int(float(read_bytes - prev_read_bytes) / seconds
> + 0.5)
> wr_rate = int(float(write_bytes - prev_write_bytes) /
> seconds + 0.5)
>
> - self.host_stats.update({'disk_read_rate': rd_rate,
> - 'disk_write_rate': wr_rate,
> - 'disk_read_bytes': read_bytes,
> - 'disk_write_bytes': write_bytes})
> + self.host_stats['disk_read_rate'].append(rd_rate)
> + self.host_stats['disk_write_rate'].append(wr_rate)
> + self.host_stats['disk_read_bytes'].append(read_bytes)
> + self.host_stats['disk_write_bytes'].append(write_bytes)
>
> def _get_host_network_io_rate(self, seconds):
> - prev_recv_bytes = self.host_stats['net_recv_bytes']
> - prev_sent_bytes = self.host_stats['net_sent_bytes']
> + net_recv_bytes = self.host_stats['net_recv_bytes']
> + net_sent_bytes = self.host_stats['net_sent_bytes']
> + prev_recv_bytes = net_recv_bytes[-1] if net_recv_bytes else 0
> + prev_sent_bytes = net_sent_bytes[-1] if net_sent_bytes else 0
>
> net_ios = psutil.network_io_counters(True)
> recv_bytes = 0
> @@ -202,10 +212,24 @@ class HostStatsModel(object):
> rx_rate = int(float(recv_bytes - prev_recv_bytes) / seconds
> + 0.5)
> tx_rate = int(float(sent_bytes - prev_sent_bytes) / seconds
> + 0.5)
>
> - self.host_stats.update({'net_recv_rate': rx_rate,
> - 'net_sent_rate': tx_rate,
> - 'net_recv_bytes': recv_bytes,
> - 'net_sent_bytes': sent_bytes})
> + self.host_stats['net_recv_rate'].append(rx_rate)
> + self.host_stats['net_sent_rate'].append(tx_rate)
> + self.host_stats['net_recv_bytes'].append(recv_bytes)
> + self.host_stats['net_sent_bytes'].append(sent_bytes)
> +
> +
> +class HostStatsHistoryModel(object):
> + def __init__(self, **kargs):
> + self.history = HostStatsModel(**kargs)
> + pass
"Pass" is not necessary
ops...
I will remove before applying
> +
> + def lookup(self, *name):
> + return {'cpu_utilization':
> self.history.host_stats['cpu_utilization'],
> + 'memory': self.history.host_stats['memory'],
> + 'disk_read_rate':
> self.history.host_stats['disk_read_rate'],
> + 'disk_write_rate':
> self.history.host_stats['disk_write_rate'],
> + 'net_recv_rate':
> self.history.host_stats['net_recv_rate'],
> + 'net_sent_rate':
> self.history.host_stats['net_sent_rate']}
>
>
> class PartitionsModel(object):