Kaynağa Gözat

实现磁盘类别分布及总量统计,实现虚拟机CPU top 10展现

James Iter 9 yıl önce
ebeveyn
işleme
c39a050e77
5 değiştirilmiş dosya ile 117 ekleme ve 42 silme
  1. 30 0
      api/disk.py
  2. 1 0
      api_route_table.py
  3. 1 0
      models/initialize.py
  4. 51 40
      templates/dashboard.html
  5. 34 2
      views/dashboard.py

+ 30 - 0
api/disk.py

@@ -235,3 +235,33 @@ def r_update(uuid):
     except ji.PreviewingError, e:
         return json.loads(e.message)
 
+
+@Utils.dumps2response
+def r_distribute_count():
+    from models import Disk
+    rows, count = Disk.get_all()
+
+    ret = dict()
+    ret['state'] = ji.Common.exchange_state(20000)
+
+    ret['data'] = {
+        'kind': {'system': 0, 'data_mounted': 0, 'data_idle': 0},
+        'total_size': 0,
+        'disks': rows.__len__()
+    }
+
+    for disk in rows:
+        if disk['sequence'] == 0:
+            ret['data']['kind']['system'] += 1
+
+        elif disk['sequence'] < 0:
+            ret['data']['kind']['data_idle'] += 1
+
+        else:
+            ret['data']['kind']['data_mounted'] += 1
+
+        ret['data']['total_size'] += disk['size']
+
+    return ret
+
+

+ 1 - 0
api_route_table.py

@@ -85,6 +85,7 @@ add_rule_api(disk.blueprint, '/<uuid>', api_func='disk.r_update', methods=['PATC
 add_rule_api(disk.blueprints, '/<uuids>', api_func='disk.r_get', methods=['GET'])
 add_rule_api(disk.blueprints, '', api_func='disk.r_get_by_filter', methods=['GET'])
 add_rule_api(disk.blueprints, '/_search', api_func='disk.r_content_search', methods=['GET'])
+add_rule_api(disk.blueprints, '/_distribute_count', api_func='disk.r_distribute_count', methods=['GET'])
 
 # 日志查询
 # 系统模板操作

+ 1 - 0
models/initialize.py

@@ -125,3 +125,4 @@ dev_table = list()
 for i in range(26):
     dev_table.append('vd' + chr(97 + i))
 
+app.jinja_env.add_extension('jinja2.ext.loopcontrols')

+ 51 - 40
templates/dashboard.html

@@ -1,34 +1,20 @@
 {% extends "layout.html" %}
 {% block head %}
     {{ super() }}
+
+    <style type="text/css">
+        [class^="content-box"] {
+            border-radius: 0 !important;
+        }
+    </style>
 {% endblock head %}
 {% block content %}
 
 <script type="text/javascript">
-    var page = 1;
-    var page_size = 10;
-    var keyword = '';
     var resource_path = window.location.pathname;
     var cur_url = resource_path;
 
     $(document).ready(function() {
-        cur_url = resource_path + '?page=' + page + '&page_size=' + page_size;
-
-        var last_ready = null;
-        $('#content_search').keydown(function() {
-            if (last_ready !== null) {
-                clearTimeout(last_ready);
-            }
-            last_ready = setTimeout(function () {
-                keyword = $('#content_search').val();
-                cur_url = resource_path + '?page=' + page + '&page_size=' + page_size;
-                if (keyword.length > 0) {
-                    cur_url = resource_path + '?page=' + page + '&page_size=' + page_size + '&keyword=' + keyword;
-                }
-                window.location.href=cur_url;
-            }, 1000);
-        });
-
         $('body').addClass('add-transition');
         $('.add-page-transition').on('click', function(){
             var transAttr = $(this).attr('data-transition');
@@ -36,25 +22,6 @@
             $('.add-transition').addClass(transAttr);
         });
     });
-
-    function refresh() {
-        keyword = $('#content_search').val();
-        page = $('#pagination li.active a').text();
-        page_size = $('#page_size').val();
-        cur_url = resource_path + '?page=' + page + '&page_size=' + page_size;
-        if (keyword.length > 0) {
-            cur_url = resource_path + '?page=' + page + '&page_size=' + page_size + '&keyword=' + keyword;
-        }
-        window.location.href=cur_url;
-    }
-
-    function panel_onmouseover(me) {
-        $(me).find(".show_detail_link").css('display','block');
-    }
-
-    function panel_onmouseout(me) {
-        $(me).find(".show_detail_link").css('display','none');
-    }
 </script>
     <div class="panel">
         <div class="panel-body">
@@ -120,7 +87,7 @@
                             <div class="tile-content-wrapper">
                                 <i class="webhh icon-diskspace"></i>
                                 <div style="font-size: 20px; margin-top: 18px; right: 10px; position: absolute;">
-                                    103733 GB
+                                    {{ disks_distribute_count_ret.data.total_size }} GB
                                 </div>
                                 <div class="tile-header" style="opacity: .70;">
                                     虚拟机磁盘空间总计
@@ -132,4 +99,48 @@
             </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 bg-blue-alt">
+                            CPU
+                        </h3>
+                        <div class="content-box-wrapper" style="padding-top: 0;">
+                            <table class="table mrg0B mrg10T">
+                                <thead>
+                                <tr>
+                                    <td style="width: 65%;">实例</td>
+                                    <td>负载</td>
+                                </tr>
+                                </thead>
+                                <tbody>
+                                {% for item in guests_current_top_10_ret.data.cpu_load %}
+                                    {% if item.guest_uuid not in guests_mapping_by_uuid %}{% continue %}{% endif %}
+                                <tr>
+                                    <td class="text-left">
+                                        <a href="/guest/detail/{{ item.guest_uuid }}">
+                                            {{ guests_mapping_by_uuid[item.guest_uuid].label }}/{{ guests_mapping_by_uuid[item.guest_uuid].remark }}
+                                        </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>
+        </div>
+    </div>
 {% endblock content %}

+ 34 - 2
views/dashboard.py

@@ -21,13 +21,14 @@ blueprint = Blueprint(
 
 
 def show():
-    args = list()
     resource_path = request.path
 
     host_url = request.host_url.rstrip('/')
 
     hosts_url = host_url + url_for('api_hosts.r_get_by_filter')
     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_ret = requests.get(url=hosts_url)
     hosts_ret = json.loads(hosts_ret.content)
@@ -35,6 +36,34 @@ def show():
     guests_distribute_count_ret = requests.get(url=guests_distribute_count_url)
     guests_distribute_count_ret = json.loads(guests_distribute_count_ret.content)
 
+    disks_distribute_count_ret = requests.get(url=disks_distribute_count_url)
+    disks_distribute_count_ret = json.loads(disks_distribute_count_ret.content)
+
+    guests_current_top_10_ret = requests.get(url=guests_current_top_10_url)
+    guests_current_top_10_ret = json.loads(guests_current_top_10_ret.content)
+
+    guests_url = host_url + url_for('api_guests.r_get_by_filter')
+
+    guests_uuid = list()
+
+    for k, v in guests_current_top_10_ret['data'].items():
+        for item in v:
+            if 'guest_uuid' not in item:
+                break
+
+            if item['guest_uuid'] not in guests_uuid:
+                guests_uuid.append(item['guest_uuid'])
+
+    guests_url = guests_url + '?filter=uuid:in:' + ','.join(guests_uuid)
+
+    guests_ret = requests.get(url=guests_url)
+    guests_ret = json.loads(guests_ret.content)
+
+    # Guest uuid 与 Guest 的映射
+    guests_mapping_by_uuid = dict()
+    for guest in guests_ret['data']:
+        guests_mapping_by_uuid[guest['uuid']] = guest
+
     hosts_sum = {'cpu': 0, 'memory': 0}
 
     for host in hosts_ret['data']:
@@ -42,5 +71,8 @@ def show():
         hosts_sum['memory'] += host['memory']
 
     return render_template('dashboard.html', hosts_sum=hosts_sum, resource_path=resource_path,
-                           guests_distribute_count_ret=guests_distribute_count_ret)
+                           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)