Jelajahi Sumber

实现宿主机top10性能展示

James Iter 9 tahun lalu
induk
melakukan
0d1034fdde
4 mengubah file dengan 223 tambahan dan 6 penghapusan
  1. 7 4
      api/host_performance.py
  2. 194 0
      templates/dashboard.html
  3. 1 1
      templates/hosts_show.html
  4. 21 1
      views/dashboard.py

+ 7 - 4
api/host_performance.py

@@ -373,7 +373,8 @@ def r_last_the_range_minutes_top_10(_range):
     for row in rows:
         disk_uuid = '_'.join([row['node_id'].__str__(), row['mountpoint']])
         if disk_uuid not in hosts_node_id_mapping:
-            hosts_node_id_mapping[disk_uuid] = {'rw_bytes': 0, 'rw_req': 0}
+            hosts_node_id_mapping[disk_uuid] = {'rw_bytes': 0, 'rw_req': 0, 'node_id': row['node_id'],
+                                                'mountpoint': row['mountpoint']}
 
         hosts_node_id_mapping[disk_uuid]['rw_bytes'] += row['rd_bytes'] + row['wr_bytes']
         hosts_node_id_mapping[disk_uuid]['rw_req'] += row['rd_req'] + row['wr_req']
@@ -385,7 +386,8 @@ def r_last_the_range_minutes_top_10(_range):
         if v['rw_req'] == 0:
             continue
 
-        rows.append({'disk_uuid': k, 'rw_bytes': v['rw_bytes'] * 60 * _range, 'rw_req': v['rw_req'] * 60 * _range})
+        rows.append({'disk_uuid': k, 'rw_bytes': v['rw_bytes'] * 60 * _range, 'rw_req': v['rw_req'] * 60 * _range,
+                     'node_id': v['node_id'], 'mountpoint': v['mountpoint']})
 
     effective_range = length
     if rows.__len__() < length:
@@ -403,7 +405,8 @@ def r_last_the_range_minutes_top_10(_range):
     for row in rows:
         nic_uuid = '_'.join([row['node_id'].__str__(), row['name']])
         if nic_uuid not in hosts_node_id_mapping:
-            hosts_node_id_mapping[nic_uuid] = {'rt_bytes': 0, 'rt_packets': 0}
+            hosts_node_id_mapping[nic_uuid] = {'rt_bytes': 0, 'rt_packets': 0, 'node_id': row['node_id'],
+                                               'name': row['name']}
 
         hosts_node_id_mapping[nic_uuid]['rt_bytes'] += row['rx_bytes'] + row['tx_bytes']
         hosts_node_id_mapping[nic_uuid]['rt_packets'] += row['rx_packets'] + row['tx_packets']
@@ -416,7 +419,7 @@ def r_last_the_range_minutes_top_10(_range):
             continue
 
         rows.append({'nic_uuid': k, 'rt_bytes': v['rt_bytes'] * 60 * _range,
-                     'rt_packets': v['rt_packets'] * 60 * _range})
+                     'rt_packets': v['rt_packets'] * 60 * _range, 'node_id': v['node_id'], 'name': v['name']})
 
     effective_range = length
     if rows.__len__() < length:

+ 194 - 0
templates/dashboard.html

@@ -265,4 +265,198 @@
             </div>
         </div>
     </div>
+    <div class="panel">
+        <div class="panel-body">
+            <h3 class="title-hero">
+                宿主机 TOP <span style="font-size: 17px;">10</span>
+            </h3>
+            <div class="row">
+                <div class="col-md-4">
+                    <div class="content-box">
+                        <h3 class="content-box-header btn-info">
+                            CPU
+                        </h3>
+                        <div class="content-box-wrapper" style="padding-top: 0;">
+                            <table class="table mrg0B mrg10T">
+                                <thead>
+                                <tr>
+                                    <td style="width: 65%;">实例</td>
+                                    <td style="width: 35%;">负载</td>
+                                </tr>
+                                </thead>
+                                <tbody>
+                                {% for item in hosts_current_top_10_ret.data.cpu_load %}
+                                    {% if item.node_id not in hosts_mapping_by_node_id %}{% continue %}{% endif %}
+                                    <tr>
+                                        <td class="text-left" style="text-overflow: ellipsis; white-space: nowrap; overflow: hidden;">
+                                            <a href="/host/detail/{{ item.node_id }}">
+                                                {{ hosts_mapping_by_node_id[item.node_id].hostname }}
+                                            </a>
+                                        </td>
+                                        <td>
+                                            <div class="progressbar-small progressbar" data-value="{{ item.cpu_load }}">
+                                                <div class="progressbar-value tooltip-button {% if item.cpu_load >= 85 %}bg-red{% elif item.cpu_load >= 65 %}bg-orange{% else %}bg-green{% endif %}" title="{{ item.cpu_load }}%">
+                                                </div>
+                                            </div>
+                                        </td>
+                                    </tr>
+                                {% endfor %}
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+                <div class="col-md-4">
+                    <div class="content-box">
+                        <h3 class="content-box-header" style="background-color: #8e8e8e; color: #fff;">
+                            磁盘 IOPS
+                        </h3>
+                        <div class="content-box-wrapper" style="padding-top: 0;">
+                            <table class="table mrg0B mrg10T" style="table-layout: fixed;">
+                                <thead>
+                                <tr>
+                                    <td style="width: 65%;">实例</td>
+                                    <td style="width: 35%;">IOPS</td>
+                                </tr>
+                                </thead>
+                                <tbody>
+                                {% for item in hosts_current_top_10_ret.data.rw_req %}
+                                    {% if item.node_id not in hosts_mapping_by_node_id %}{% continue %}{% endif %}
+                                    <tr>
+                                        <td class="text-left" style="text-overflow: ellipsis; white-space: nowrap; overflow: hidden;">
+                                            <a href="/disk/detail/{{ item.node_id }}/{{ item.mountpoint }}">
+                                                {{ hosts_mapping_by_node_id[item.node_id].hostname }}({{ item.mountpoint }})
+                                            </a>
+                                        </td>
+                                        <td>
+                                            {{ item.rw_req }}
+                                        </td>
+                                    </tr>
+                                {% endfor %}
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+                <div class="col-md-4">
+                    <div class="content-box">
+                        <h3 class="content-box-header" style="background-color: #8e8e8e; color: #fff;">
+                            磁盘吞吐量
+                        </h3>
+                        <div class="content-box-wrapper" style="padding-top: 0;">
+                            <table class="table mrg0B mrg10T" style="table-layout: fixed;">
+                                <thead>
+                                <tr>
+                                    <td style="width: 65%;">实例</td>
+                                    <td style="width: 35%;">吞吐量</td>
+                                </tr>
+                                </thead>
+                                <tbody>
+                                {% for item in hosts_current_top_10_ret.data.rw_bytes %}
+                                    {% if item.node_id not in hosts_mapping_by_node_id %}{% continue %}{% endif %}
+                                    <tr>
+                                        <td class="text-left" style="text-overflow: ellipsis; white-space: nowrap; overflow: hidden;">
+                                            <a href="/disk/detail/{{ item.node_id }}/{{ item.mountpoint }}">
+                                                {{ hosts_mapping_by_node_id[item.node_id].hostname }}({{ item.mountpoint }})
+                                            </a>
+                                        </td>
+                                        <td>
+                                            <!-- 速率参考链接:https://en.wikipedia.org/wiki/Data_rate_units#Examples_of_bit_rates -->
+                                            {% if item.rw_bytes >= 1024**3 %}
+                                                {{ '%0.1f'| format(item.rw_bytes / 1024**3) }} GBps
+                                            {% elif item.rw_bytes >= 1024**2 %}
+                                                {{ '%0.1f'| format(item.rw_bytes / 1024**2) }} MBps
+                                            {% elif item.rw_bytes >= 1024 %}
+                                                {{ '%0.1f'| format(item.rw_bytes / 1024) }} KBps
+                                            {% else %}
+                                                {{ item.rw_bytes }} Bps
+                                            {% endif %}
+                                        </td>
+                                    </tr>
+                                {% endfor %}
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="row">
+                <div class="col-md-4">
+                    <div class="content-box">
+                        <h3 class="content-box-header bg-green">
+                            网络流量
+                        </h3>
+                        <div class="content-box-wrapper" style="padding-top: 0;">
+                            <table class="table mrg0B mrg10T">
+                                <thead>
+                                <tr>
+                                    <td style="width: 65%;">实例</td>
+                                    <td style="width: 35%;">流量</td>
+                                </tr>
+                                </thead>
+                                <tbody>
+                                {% for item in hosts_current_top_10_ret.data.rt_bytes %}
+                                    {% if item.node_id not in hosts_mapping_by_node_id %}{% continue %}{% endif %}
+                                    <tr>
+                                        <td class="text-left" style="text-overflow: ellipsis; white-space: nowrap; overflow: hidden;">
+                                            <a href="/host/detail/{{ item.node_id }}">
+                                                {{ hosts_mapping_by_node_id[item.node_id].hostname }}({{ item.name }})
+                                            </a>
+                                        </td>
+                                        <td>
+                                            <!-- 速率参考链接:https://en.wikipedia.org/wiki/Data_rate_units#Examples_of_bit_rates -->
+                                            {% if item.rt_bytes * 8 >= 1000**3 %}
+                                                {{ '%0.1f'| format(item.rt_bytes * 8 / 1000**3) }} Gbps
+                                            {% elif item.rt_bytes * 8 >= 1000**2 %}
+                                                {{ '%0.1f'| format(item.rt_bytes * 8 / 1000**2) }} Mbps
+                                            {% elif item.rt_bytes * 8 >= 1000 %}
+                                                {{ '%0.1f'| format(item.rt_bytes * 8 / 1000) }} kbps
+                                            {% else %}
+                                                {{ item.rt_bytes * 8 }} bps
+                                            {% endif %}
+                                        </td>
+                                    </tr>
+                                {% endfor %}
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+                <div class="col-md-4">
+                    <div class="content-box">
+                        <h3 class="content-box-header btn-warning">
+                            内存使用率
+                        </h3>
+                        <div class="content-box-wrapper" style="padding-top: 0;">
+                            <table class="table mrg0B mrg10T">
+                                <thead>
+                                <tr>
+                                    <td style="width: 65%;">实例</td>
+                                    <td style="width: 35%;">使用率</td>
+                                </tr>
+                                </thead>
+                                <tbody>
+                                {% for item in hosts_current_top_10_ret.data.memory_rate %}
+                                    {% if item.node_id not in hosts_mapping_by_node_id %}{% continue %}{% endif %}
+                                    <tr>
+                                        <td class="text-left" style="text-overflow: ellipsis; white-space: nowrap; overflow: hidden;">
+                                            <a href="/host/detail/{{ item.node_id }}">
+                                                {{ hosts_mapping_by_node_id[item.node_id].hostname }}
+                                            </a>
+                                        </td>
+                                        <td>
+                                            {{ item.memory_rate }}%
+                                        </td>
+                                    </tr>
+                                {% endfor %}
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+                <div class="col-md-4">
+                </div>
+            </div>
+        </div>
+    </div>
 {% endblock content %}

+ 1 - 1
templates/hosts_show.html

@@ -81,7 +81,7 @@
                                 <i style="float: right;" class="glyph-icon icon-circle font-size-23 {% if item.alive == true %}font-green{% else %}font-red{% endif %}"></i>
                             </h2>
                             <div class="bg-blue host-specs">
-                                <div class="show_detail_link" style="display: none; position: absolute; z-index: 9999; margin-left: 246px; margin-top: 20px;">
+                                <div class="show_detail_link" style="display: none; position: absolute; z-index: 9999; margin-top: 20px; right: 2%;">
                                     <a href="/host/detail/{{ item.node_id }}" style="color: white; background-color: black;">&nbsp;&nbsp;&nbsp;&nbsp;主机详情&nbsp;&nbsp;&nbsp;&nbsp;</a>
                                 </div>
                                 <span>{{ '%0.2f'| format(item.system_load[0] / item.cpu) }}</span>

+ 21 - 1
views/dashboard.py

@@ -29,10 +29,16 @@ def show():
     guests_distribute_count_url = host_url + url_for('api_guests.r_distribute_count')
     disks_distribute_count_url = host_url + url_for('api_disks.r_distribute_count')
     guests_current_top_10_url = host_url + url_for('api_performance.r_current_top_10')
+    hosts_current_top_10_url = host_url + url_for('api_host_performance.r_current_top_10')
 
     hosts_ret = requests.get(url=hosts_url)
     hosts_ret = json.loads(hosts_ret.content)
 
+    # Host node_id 与 Host 的映射
+    hosts_mapping_by_node_id = dict()
+    for host in hosts_ret['data']:
+        hosts_mapping_by_node_id[int(host['node_id'])] = host
+
     guests_distribute_count_ret = requests.get(url=guests_distribute_count_url)
     guests_distribute_count_ret = json.loads(guests_distribute_count_ret.content)
 
@@ -85,6 +91,18 @@ def show():
     for disk in disks_ret['data']:
         disks_mapping_by_uuid[disk['uuid']] = disk
 
+    hosts_current_top_10_ret = requests.get(url=hosts_current_top_10_url)
+    hosts_current_top_10_ret = json.loads(hosts_current_top_10_ret.content)
+    hosts_current_top_10_ret['data']['memory_rate'] = hosts_current_top_10_ret['data']['cpu_load']
+
+    for i in range(hosts_current_top_10_ret['data']['memory_rate'].__len__()):
+        memory_total = hosts_mapping_by_node_id[hosts_current_top_10_ret['data']['memory_rate'][i]['node_id']]['memory']
+        memory_available = hosts_current_top_10_ret['data']['memory_rate'][i]['memory_available']
+        memory_used = memory_total - memory_available
+        hosts_current_top_10_ret['data']['memory_rate'][i]['memory_rate'] = int(memory_used / float(memory_total) * 100)
+
+    hosts_current_top_10_ret['data']['memory_rate'].sort(key=lambda _k: _k['memory_rate'], reverse=True)
+
     hosts_sum = {'cpu': 0, 'memory': 0}
 
     for host in hosts_ret['data']:
@@ -95,5 +113,7 @@ def show():
                            guests_distribute_count_ret=guests_distribute_count_ret,
                            disks_distribute_count_ret=disks_distribute_count_ret,
                            guests_current_top_10_ret=guests_current_top_10_ret,
-                           guests_mapping_by_uuid=guests_mapping_by_uuid, disks_mapping_by_uuid=disks_mapping_by_uuid)
+                           guests_mapping_by_uuid=guests_mapping_by_uuid, disks_mapping_by_uuid=disks_mapping_by_uuid,
+                           hosts_current_top_10_ret=hosts_current_top_10_ret,
+                           hosts_mapping_by_node_id=hosts_mapping_by_node_id)