1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2024-12-24 15:15:22 +00:00

Added graph scale for instance

This commit is contained in:
Retspen 2015-03-20 12:06:32 +02:00
parent 02570cd826
commit 4a17f08740
5 changed files with 302 additions and 16 deletions

View file

@ -1,7 +1,9 @@
import time
import json
from string import letters, digits
from random import choice
from bisect import insort
from django.http import HttpResponseRedirect
from django.http import HttpResponse, HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.shortcuts import render
from django.utils.translation import ugettext_lazy as _
@ -408,3 +410,122 @@ def instance(request, compute_id, vname):
addlogmsg(request.user.id, instance.id, lib_err.message)
return render(request, 'instance.html', locals())
def inst_graph(request, compute_id, vname):
"""
Return instance usage
"""
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('login'))
datasets = {}
datasets_rd = []
datasets_wr = []
json_blk = []
cookie_blk = {}
blk_error = False
datasets_rx = []
datasets_tx = []
json_net = []
cookie_net = {}
net_error = False
networks = None
disks = None
points = 5
curent_time = time.strftime("%H:%M:%S")
compute = Compute.objects.get(id=compute_id)
try:
conn = wvmInstance(compute.hostname,
compute.login,
compute.password,
compute.type,
vname)
status = conn.get_status()
cpu_usage = conn.cpu_usage()
blk_usage = conn.disk_usage()
net_usage = conn.net_usage()
conn.close()
except libvirtError:
status = None
blk_usage = None
cpu_usage = None
net_usage = None
if status == 1:
cookies = request.COOKIES
if cookies.get('cpu') == '{}' or not cookies.get('cpu') or not cpu_usage:
datasets['cpu'] = [0]
datasets['timer'] = [curent_time]
else:
datasets['cpu'] = eval(cookies.get('cpu'))
datasets['timer'] = eval(cookies.get('timer'))
datasets['timer'].append(curent_time)
datasets['cpu'].append(int(cpu_usage['cpu']))
if len(datasets['timer']) > points:
datasets['timer'].pop(0)
if len(datasets['cpu']) > points:
datasets['cpu'].pop(0)
for blk in blk_usage:
if cookies.get('hdd') == '{}' or not cookies.get('hdd') or not blk_usage:
datasets_wr.append(0)
datasets_rd.append(0)
else:
datasets['hdd'] = eval(cookies.get('hdd'))
try:
datasets_rd = datasets['hdd'][blk['dev']][0]
datasets_wr = datasets['hdd'][blk['dev']][1]
except:
blk_error = True
if not blk_error:
datasets_rd.append(int(blk['rd']) / 1048576)
datasets_wr.append(int(blk['wr']) / 1048576)
if len(datasets_rd) > points:
datasets_rd.pop(0)
if len(datasets_wr) >= points + 1:
datasets_wr.pop(0)
json_blk.append({'dev': blk['dev'], 'data': [datasets_rd, datasets_wr]})
cookie_blk[blk['dev']] = [datasets_rd, datasets_wr]
for net in net_usage:
if cookies.get('net') == '{}' or not cookies.get('net') or not net_usage:
datasets_rx.append(0)
datasets_tx.append(0)
else:
datasets['net'] = eval(cookies.get('net'))
try:
datasets_rx = datasets['net'][net['dev']][0]
datasets_tx = datasets['net'][net['dev']][1]
except:
net_error = True
if not net_error:
datasets_rx.append(int(net['rx']) / 1048576)
datasets_tx.append(int(net['tx']) / 1048576)
if len(datasets_rx) > points:
datasets_rx.pop(0)
if len(datasets_tx) > points:
datasets_tx.pop(0)
json_net.append({'dev': net['dev'], 'data': [datasets_rx, datasets_tx]})
cookie_net[net['dev']] = [datasets_rx, datasets_tx]
data = json.dumps({'status': status, 'cpudata': datasets['cpu'], 'hdddata': json_blk, 'netdata': json_net, 'timeline': datasets['timer']})
response = HttpResponse()
response['Content-Type'] = "text/javascript"
if status == 1:
response.cookies['cpu'] = datasets['cpu']
response.cookies['timer'] = datasets['timer']
response.cookies['hdd'] = cookie_blk
response.cookies['net'] = cookie_net
response.write(data)
return response

View file

@ -100,7 +100,7 @@ body {
width: 65px;
}
#action-button {
.action-button {
text-align: center;
}

View file

@ -38,43 +38,43 @@
<!-- Nav tabs -->
<ul class="nav nav-pills" role="tablist">
<li role="presentation" class="active">
<a href="#power" id="action-button" aria-controls="power" role="tab" data-toggle="tab">
<a href="#power" class="action-button" aria-controls="power" role="tab" data-toggle="tab">
<span id="action-block" class="glyphicon glyphicon-off" aria-hidden="true"></span>
{% trans "Power" %}
</a>
</li>
<li role="presentation">
<a href="#access" id="action-button" aria-controls="access" role="tab" data-toggle="tab">
<a href="#access" class="action-button" aria-controls="access" role="tab" data-toggle="tab">
<span id="action-block" class="glyphicon glyphicon-lock" aria-hidden="true"></span>
{% trans "Access" %}
</a>
</li>
<li role="presentation">
<a href="#resize" id="action-button" aria-controls="resize" role="tab" data-toggle="tab">
<a href="#resize" class="action-button" aria-controls="resize" role="tab" data-toggle="tab">
<span id="action-block" class="glyphicon glyphicon-resize-full" aria-hidden="true"></span>
{% trans "Resize" %}
</a>
</li>
<li role="presentation">
<a href="#snapshots" id="action-button" aria-controls="snapshots" role="tab" data-toggle="tab">
<a href="#snapshots" class="action-button" aria-controls="snapshots" role="tab" data-toggle="tab">
<span id="action-block" class="glyphicon glyphicon-camera" aria-hidden="true"></span>
{% trans "Snapshots" %}
</a>
</li>
<li role="presentation">
<a href="#settings" id="action-button" aria-controls="settings" role="tab" data-toggle="tab">
<a href="#settings" class="action-button" aria-controls="settings" role="tab" data-toggle="tab">
<span id="action-block" class="glyphicon glyphicon-cog" aria-hidden="true"></span>
{% trans "Settings" %}
</a>
</li>
<li role="presentation">
<a href="#graphics" id="action-button" aria-controls="graphics" role="tab" data-toggle="tab">
<a href="#graphics" id="chartgraphs" class="action-button" aria-controls="graphics" role="tab" data-toggle="tab">
<span id="action-block" class="glyphicon glyphicon-signal" aria-hidden="true"></span>
{% trans "Graphs" %}
</a>
</li>
<li role="presentation">
<a href="#undefine" id="action-button" aria-controls="undefine" role="tab" data-toggle="tab">
<a href="#undefine" class="action-button" aria-controls="undefine" role="tab" data-toggle="tab">
<span id="action-block" class="glyphicon glyphicon-trash" aria-hidden="true"></span>
{% trans "Destroy" %}
</a>
@ -689,15 +689,55 @@
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">
<a href="#graps" aria-controls="graps" role="tab" data-toggle="tab">
<a href="#graphs" aria-controls="graphs" role="tab" data-toggle="tab">
{% trans "Real Time" %}
</a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="graps">
<p>Graphics</p>
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="graphs">
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-long-arrow-right"></i> {% trans "CPU usage" %}</h3>
</div>
<div class="panel-body">
<div class="flot-chart">
<div class="flot-chart-content" id="flot-moving-line-chart" style="padding: 0px; position: relative;">
<canvas id="cpuChart" width="735" height="250"></canvas>
</div>
</div>
</div>
</div>
{% for net in networks %}
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-long-arrow-right"></i> {% trans "Bandwidth device:" %} eth{{ forloop.counter0 }}</h3>
</div>
<div class="panel-body">
<div class="flot-chart">
<div class="flot-chart-content" id="flot-moving-line-chart" style="padding: 0px; position: relative;">
<canvas id="netEth{{ forloop.counter0 }}Chart" width="735" height="250"></canvas>
</div>
</div>
</div>
</div>
{% endfor %}
{% for disk in disks %}
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-long-arrow-right"></i> {% trans "Disk I/O device:" %} {{ disk.dev }}</h3>
</div>
<div class="panel-body">
<div class="flot-chart">
<div class="flot-chart-content" id="flot-moving-line-chart" style="padding: 0px; position: relative;">
<canvas id="blk{{ disk.dev }}Chart" width="735" height="250"></canvas>
</div>
</div>
</div>
</div>
{% endfor %}
<div class="clearfix"></div>
</div>
</div>
</div>
@ -827,5 +867,127 @@
toggles.toggle();
});
});
</script>
<script src="{{ STATIC_URL }}js/Chart.min.js"></script>
<script>
$( "#graphics" ).click();
</script>
<script>
$('#chartgraphs').on('shown.bs.tab', function (e) {
var cpuLineData = {
labels : [0, 0, 0, 0, 0],
datasets : [
{
fillColor: "rgba(241,72,70,0.5)",
strokeColor: "rgba(241,72,70,1)",
pointColor : "rgba(241,72,70,1)",
pointStrokeColor : "#fff",
pointHighlightFill : "#fff",
pointHighlightStroke : "rgba(220,220,220,1)",
data : [0, 0, 0, 0, 0]
}
]
};
var diskLineData = {
labels : [0, 0, 0, 0, 0],
datasets : [
{
"fillColor": "rgba(83,191,189,0.5)",
"strokeColor": "rgba(83,191,189,1)",
"pointColor": "rgba(83,191,189,1)",
"pointStrokeColor": "#fff",
"data": [0, 0, 0, 0, 0]
},
{
"fillColor": "rgba(249,134,33,0.5)",
"strokeColor": "rgba(249,134,33,1)",
"pointColor": "rgba(249,134,33,1)",
"pointStrokeColor": "#fff",
"data": [0, 0, 0, 0, 0]
},
]
}
var netLineData = {
labels : [0, 0, 0, 0, 0],
datasets : [
{
"fillColor": "rgba(83,191,189,0.5)",
"strokeColor": "rgba(83,191,189,1)",
"pointColor": "rgba(83,191,189,1)",
"pointStrokeColor": "#fff",
"data": [0, 0, 0, 0, 0]
},
{
"fillColor": "rgba(151,187,205,0.5)",
"strokeColor": "rgba(151,187,205,1)",
"pointColor": "rgba(151,187,205,1)",
"pointStrokeColor": "#fff",
"data": [0, 0, 0, 0, 0]
},
]
}
var cpuOpt = {
animation: false,
pointDotRadius: 2,
scaleLabel: "<%=value%> %",
scaleOverride: true,
scaleSteps: 10,
scaleStepWidth: 10,
scaleStartValue: 0,
responsive: true
};
var diskOpt = {
animation: false,
pointDotRadius: 2,
scaleLabel: "<%=value%> Mb/s",
responsive: true
};
var netOpt = {
animation: false,
pointDotRadius: 2,
scaleLabel: "<%=value%> Mbps",
responsive: true
};
var cpu_ctx = $("#cpuChart").get(0).getContext("2d");
var cpuChart = new Chart(cpu_ctx).Line(cpuLineData, cpuOpt);
var diskChart = {};
{% for disk in disks %}
var disk_ctx_{{ disk.dev }} = $("#blk{{ disk.dev }}Chart").get(0).getContext("2d");
diskChart['{{ disk.dev }}'] = new Chart(disk_ctx_{{ disk.dev }}).Line(diskLineData, diskOpt);
{% endfor %}
var netChart = {};
{% for net in networks %}
var net_ctx_{{ forloop.counter0 }} = $("#netEth{{ forloop.counter0 }}Chart").get(0).getContext("2d");
netChart['{{ forloop.counter0 }}'] = new Chart(net_ctx_{{ forloop.counter0 }}).Line(netLineData, netOpt);
{% endfor %}
function graph_usage() {
$.getJSON('{% url 'inst_graph' compute_id vname %}', function (data) {
cpuChart.scale.xLabels = data.timeline;
for (var i = 0; i < 5; i++) {
cpuChart.datasets[0].points[i].value = data.cpudata[i];
}
cpuChart.update();
});
}
{##}
{# $(function(f) {#}
{# window.setInterval('graph_usage()', 2000);#}
{# });#}
});
</script>
{% endblock %}

View file

@ -81,7 +81,7 @@
</div>
{% endblock %}
{% block script %}
<script src="{{ STATIC_URL }}/js/Chart.min.js"></script>
<script src="{{ STATIC_URL }}js/Chart.min.js"></script>
<script>
var cpuLineData = {
labels : [0, 0, 0, 0, 0],
@ -133,7 +133,7 @@
responsive: true
});
function hostusage() {
function graph_usage() {
$.getJSON('{% url 'compute_graph' compute_id %}', function (data) {
cpuChart.scale.xLabels = data.timeline;
memChart.scale.xLabels = data.timeline;
@ -145,8 +145,9 @@
memChart.update();
});
}
$(function () {
window.setInterval('hostusage()', 4000);
window.setInterval(graph_usage(), 4000);
});
</script>
{% endblock %}

View file

@ -12,6 +12,8 @@ urlpatterns = patterns('',
url(r'^instances$', 'instances.views.instances', name='instances'),
url(r'^instance/(\d+)/([\w\-\.]+)/$', 'instances.views.instance', name='instance'),
url(r'^instance/statistics/(\d+)/([\w\-\.]+)/$', 'instances.views.inst_graph', name='inst_graph'),
url(r'^computes/$', 'computes.views.computes', name='computes'),
url(r'^compute/overview/(\d+)/$', 'computes.views.overview', name='overview'),