Răsfoiți Sursa

对dashoboard进行了前后端分离

James Iter 8 ani în urmă
părinte
comite
4bb728971a
9 a modificat fișierele cu 172 adăugiri și 109 ștergeri
  1. 1 1
      README.md
  2. 131 0
      api/dashboard.py
  3. 4 0
      api_route_table.py
  4. 7 0
      docs/todo.md
  5. 4 0
      main.py
  6. 1 0
      models/event_processor.py
  7. 2 2
      models/host.py
  8. 10 13
      templates/dashboard.html
  9. 12 93
      views/dashboard.py

+ 1 - 1
README.md

@@ -115,7 +115,7 @@ JimV 是一个,结构清晰简单,易于部署、维护、使用的,低门
    # NFS 客户端
    yum install nfs-utils -y
    mkdir /opt/template_images
-   echo "x.x.x.x:/srv/nfs_template_images       /opt/template_images      nfs4    defaults  0 0" >> /etc/fstab
+   echo "x.x.x.x:/srv/nfs_template_images       /opt/template_images      nfs4    soft  0 0" >> /etc/fstab
    mount -a
    ```
 

+ 131 - 0
api/dashboard.py

@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+
+import requests
+import json
+import copy
+import jimit as ji
+from flask import url_for, request, Blueprint
+
+from models import Utils
+
+
+__author__ = 'James Iter'
+__date__ = '2018/9/9'
+__contact__ = 'james.iter.cn@gmail.com'
+__copyright__ = '(c) 2018 by James Iter.'
+
+
+blueprint = Blueprint(
+    'api_dashboard',
+    __name__,
+    url_prefix='/api/dashboard'
+)
+
+blueprints = Blueprint(
+    'api_dashboards',
+    __name__,
+    url_prefix='/api/dashboards'
+)
+
+
+@Utils.dumps2response
+def r_show():
+    ret = dict()
+    ret['state'] = ji.Common.exchange_state(20000)
+
+    # alive 的布尔值 True,在 url 中传输前,会自动转换为字符串 'True'
+    hosts_url = url_for('api_hosts.r_get_by_filter', _external=True, alive=True)
+    guests_distribute_count_url = url_for('api_guests.r_distribute_count', _external=True)
+    disks_distribute_count_url = url_for('api_disks.r_distribute_count', _external=True)
+    guests_current_top_10_url = url_for('api_guest_performance.r_current_top_10', _external=True)
+    hosts_current_top_10_url = url_for('api_host_performance.r_current_top_10', _external=True)
+
+    hosts_ret = requests.get(url=hosts_url, cookies=request.cookies)
+    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, cookies=request.cookies)
+    guests_distribute_count_ret = json.loads(guests_distribute_count_ret.content)
+
+    disks_distribute_count_ret = requests.get(url=disks_distribute_count_url, cookies=request.cookies)
+    disks_distribute_count_ret = json.loads(disks_distribute_count_ret.content)
+
+    guests_current_top_10_ret = requests.get(url=guests_current_top_10_url, cookies=request.cookies)
+    guests_current_top_10_ret = json.loads(guests_current_top_10_ret.content)
+
+    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 = url_for('api_guests.r_get_by_filter', _external=True, filter='uuid:in:' + ','.join(guests_uuid))
+
+    guests_ret = requests.get(url=guests_url, cookies=request.cookies)
+    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
+
+    disks_uuid = list()
+    for k, v in guests_current_top_10_ret['data'].items():
+        for item in v:
+            if 'disk_uuid' not in item:
+                break
+
+            if item['disk_uuid'] not in disks_uuid:
+                disks_uuid.append(item['disk_uuid'])
+
+    disks_url = url_for('api_disks.r_get_by_filter', _external=True, filter='uuid:in:' + ','.join(disks_uuid))
+
+    disks_ret = requests.get(url=disks_url, cookies=request.cookies)
+    disks_ret = json.loads(disks_ret.content)
+
+    # Disk uuid 与 Disk 的映射
+    disks_mapping_by_uuid = dict()
+    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, cookies=request.cookies)
+    hosts_current_top_10_ret = json.loads(hosts_current_top_10_ret.content)
+    hosts_current_top_10_ret['data']['memory_rate'] = copy.copy(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']:
+        hosts_sum['cpu'] += host['cpu']
+        hosts_sum['memory'] += host['memory']
+
+    ret['data'] = {
+        'hosts_sum': hosts_sum,
+        '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,
+        'hosts_current_top_10_ret': hosts_current_top_10_ret,
+        'hosts_mapping_by_node_id': hosts_mapping_by_node_id
+    }
+
+    return ret
+

+ 4 - 0
api_route_table.py

@@ -3,6 +3,7 @@
 
 
 from models.utils import add_rule_api
+from api import dashboard
 from api import config
 from api import user
 from api import guest
@@ -32,6 +33,9 @@ add_rule_api(config.blueprint, '', api_func='config.r_update', methods=['PATCH']
 add_rule_api(config.blueprint, '/_quota', api_func='config.r_update_quota', methods=['PATCH'])
 add_rule_api(config.blueprint, '', api_func='config.r_get', methods=['GET'])
 
+# JimV 配置操作
+add_rule_api(dashboard.blueprint, '/_show', api_func='dashboard.r_show', methods=['GET'])
+
 # 用户管理
 add_rule_api(user.blueprint, '/_sign_in', api_func='user.r_sign_in', methods=['POST'])
 add_rule_api(user.blueprint, '/_sign_out', api_func='user.r_sign_out', methods=['GET'])

+ 7 - 0
docs/todo.md

@@ -90,4 +90,11 @@
 - [x] 修复JimV-C 先 Redis 启动后,JimV-C event_processor Redis lpop 异常的问题
 - [x] 计算节点以 JimV-C 为第一 NTP 服务器
 - [ ] 数据库时间戳,采用 JimV-N 的时间。避免 JimV-C 挂掉后,监控数据批量集中在同一个时间点上
+- [ ] 加入监控图标汇聚功能,时间范围内的平均值、最高值
+- [ ] 加入 About 页面
+- [ ] 在 About 页面,展现当前版本号
+- [ ] 在 About 页面,展现是否可以升级信息
+- [ ] 在 About 页面,加入更新功能
+- [ ] 大于 内存、负载 百分比后,禁止创建虚拟机
+
 

+ 4 - 0
main.py

@@ -57,6 +57,8 @@ from api.guest_performance import blueprint as performance_blueprint
 from api.guest_performance import blueprints as performance_blueprints
 from api.host_performance import blueprint as host_performance_blueprint
 from api.host_performance import blueprints as host_performance_blueprints
+from api.dashboard import blueprint as dashboard_blueprint
+from api.dashboard import blueprints as dashboard_blueprints
 
 from views.error_pages import *
 from views.config import blueprint as view_config_blueprint
@@ -251,6 +253,8 @@ try:
     app.register_blueprint(performance_blueprints)
     app.register_blueprint(host_performance_blueprint)
     app.register_blueprint(host_performance_blueprints)
+    app.register_blueprint(dashboard_blueprint)
+    app.register_blueprint(dashboard_blueprints)
 
     app.register_blueprint(view_config_blueprint)
     app.register_blueprint(view_misc_blueprint)

+ 1 - 0
models/event_processor.py

@@ -144,6 +144,7 @@ class EventProcessor(object):
             'boot_time': cls.message['message']['boot_time'],
             'nonrandom': False,
             'threads_status': cls.message['message']['threads_status'],
+            'version': cls.message['message']['version'],
             'timestamp': ji.Common.ts()
         }
 

+ 2 - 2
models/host.py

@@ -23,10 +23,10 @@ class Host(object):
     @staticmethod
     def alive_check(v):
         """
-        JimV-C 2 秒更新一次宿主机信息,这里以 5 秒内没收到更新,作为判断宿主机是否在线的标准
+        60 秒内没收到更新,作为判断 [计算节点] 是否在线的标准。包含了 [计算节点] 与 [控制节点] 间的时间差。
         """
 
-        coupler_length = 5
+        coupler_length = 60
 
         if 'timestamp' not in v:
             return v

+ 10 - 13
templates/dashboard.html

@@ -11,9 +11,6 @@
 {% block content %}
 
 <script type="text/javascript">
-    var resource_path = window.location.pathname;
-    var cur_url = resource_path;
-
     $(document).ready(function() {
         $('body').addClass('add-transition');
         $('.add-page-transition').on('click', function(){
@@ -316,11 +313,11 @@
                                 </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 %}
+                                    {% if item.node_id | string 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 }}
+                                                {{ hosts_mapping_by_node_id[item.node_id | string].hostname }}
                                             </a>
                                         </td>
                                         <td>
@@ -351,11 +348,11 @@
                                 </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 %}
+                                    {% if item.node_id | string 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.mountpoint }})
+                                                {{ hosts_mapping_by_node_id[item.node_id | string].hostname }}({{ item.mountpoint }})
                                             </a>
                                         </td>
                                         <td>
@@ -383,11 +380,11 @@
                                 </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 %}
+                                    {% if item.node_id | string 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.mountpoint }})
+                                                {{ hosts_mapping_by_node_id[item.node_id | string].hostname }}({{ item.mountpoint }})
                                             </a>
                                         </td>
                                         <td>
@@ -426,11 +423,11 @@
                                 </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 %}
+                                    {% if item.node_id | string 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 }})
+                                                {{ hosts_mapping_by_node_id[item.node_id | string].hostname }}({{ item.name }})
                                             </a>
                                         </td>
                                         <td>
@@ -467,11 +464,11 @@
                                 </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 %}
+                                    {% if item.node_id | string 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 }}
+                                                {{ hosts_mapping_by_node_id[item.node_id | string].hostname }}
                                             </a>
                                         </td>
                                         <td>

+ 12 - 93
views/dashboard.py

@@ -5,7 +5,6 @@
 import json
 from flask import Blueprint, render_template, url_for, request
 import requests
-import copy
 
 
 __author__ = 'James Iter'
@@ -22,96 +21,16 @@ blueprint = Blueprint(
 
 
 def show():
-    resource_path = request.path
-
-    host_url = request.host_url.rstrip('/')
-
-    # alive 的布尔值 True,在 url 中传输前,会自动转换为字符串 'True'
-    hosts_url = host_url + url_for('api_hosts.r_get_by_filter', alive=True)
-    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_guest_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, cookies=request.cookies)
-    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, cookies=request.cookies)
-    guests_distribute_count_ret = json.loads(guests_distribute_count_ret.content)
-
-    disks_distribute_count_ret = requests.get(url=disks_distribute_count_url, cookies=request.cookies)
-    disks_distribute_count_ret = json.loads(disks_distribute_count_ret.content)
-
-    guests_current_top_10_ret = requests.get(url=guests_current_top_10_url, cookies=request.cookies)
-    guests_current_top_10_ret = json.loads(guests_current_top_10_ret.content)
-
-    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 = host_url + url_for('api_guests.r_get_by_filter', filter='uuid:in:' + ','.join(guests_uuid))
-
-    guests_ret = requests.get(url=guests_url, cookies=request.cookies)
-    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
-
-    disks_uuid = list()
-    for k, v in guests_current_top_10_ret['data'].items():
-        for item in v:
-            if 'disk_uuid' not in item:
-                break
-
-            if item['disk_uuid'] not in disks_uuid:
-                disks_uuid.append(item['disk_uuid'])
-
-    disks_url = host_url + url_for('api_disks.r_get_by_filter', filter='uuid:in:' + ','.join(disks_uuid))
-
-    disks_ret = requests.get(url=disks_url, cookies=request.cookies)
-    disks_ret = json.loads(disks_ret.content)
-
-    # Disk uuid 与 Disk 的映射
-    disks_mapping_by_uuid = dict()
-    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, cookies=request.cookies)
-    hosts_current_top_10_ret = json.loads(hosts_current_top_10_ret.content)
-    hosts_current_top_10_ret['data']['memory_rate'] = copy.copy(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']:
-        hosts_sum['cpu'] += host['cpu']
-        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,
-                           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,
-                           hosts_current_top_10_ret=hosts_current_top_10_ret,
-                           hosts_mapping_by_node_id=hosts_mapping_by_node_id)
+    url = url_for('api_dashboard.r_show', _external=True)
+    ret = requests.get(url=url, cookies=request.cookies)
+    ret = json.loads(ret.content)
+
+    return render_template('dashboard.html', hosts_sum=ret['data']['hosts_sum'],
+                           guests_distribute_count_ret=ret['data']['guests_distribute_count_ret'],
+                           disks_distribute_count_ret=ret['data']['disks_distribute_count_ret'],
+                           guests_current_top_10_ret=ret['data']['guests_current_top_10_ret'],
+                           guests_mapping_by_uuid=ret['data']['guests_mapping_by_uuid'],
+                           disks_mapping_by_uuid=ret['data']['disks_mapping_by_uuid'],
+                           hosts_current_top_10_ret=ret['data']['hosts_current_top_10_ret'],
+                           hosts_mapping_by_node_id=ret['data']['hosts_mapping_by_node_id'])