[Kimchi-devel] [PATCH 1/2] Add API to return host stats history

Aline Manera alinefm at linux.vnet.ibm.com
Mon Apr 28 14:32:41 UTC 2014


On 04/24/2014 03:46 PM, Rodrigo Trujillo wrote:
> On 04/22/2014 09:41 PM, Aline Manera wrote:
>> From: Aline Manera <alinefm at 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 at 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):
>




More information about the Kimchi-devel mailing list