mirror of
				https://github.com/retspen/webvirtcloud
				synced 2025-07-31 12:41:08 +00:00 
			
		
		
		
	Update chartjs for instance statistics and add memory usage info for instances
This commit is contained in:
		
							parent
							
								
									9ab198bd8c
								
							
						
					
					
						commit
						181bd9d392
					
				
					 2 changed files with 263 additions and 172 deletions
				
			
		|  | @ -1230,6 +1230,18 @@ | |||
|                                                         </div> | ||||
|                                                     </div> | ||||
|                                                 </div> | ||||
|                                                 <div class="panel panel-default"> | ||||
|                                                     <div class="panel-heading"> | ||||
|                                                         <h3 class="panel-title"><i class="fa fa-long-arrow-right"></i> {% trans "Memory 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="memChart" width="735" height="160"></canvas> | ||||
|                                                             </div> | ||||
|                                                         </div> | ||||
|                                                     </div> | ||||
|                                                 </div> | ||||
|                                                 {% for net in networks %} | ||||
|                                                     <div class="panel panel-info"> | ||||
|                                                         <div class="panel-heading"> | ||||
|  | @ -1332,7 +1344,6 @@ | |||
| 
 | ||||
|             $.each(data['vols'], function(i, item) { | ||||
|                 $("#vols").append('<option value=' + item +'>' + item + '</option>'); | ||||
| 
 | ||||
|             }) | ||||
|         }); | ||||
| 
 | ||||
|  | @ -1568,136 +1579,274 @@ $(document).ready(function () { | |||
|         }); | ||||
|     }); | ||||
| </script> | ||||
| <script src="{% static "js/Chart.min.js" %}"></script> | ||||
| <script src="{% static "js/Chart.bundle.min.js" %}"></script> | ||||
| <script> | ||||
|     $('#chartgraphs').on('shown.bs.tab', function (event) { | ||||
|         var cpuLineData = { | ||||
|             labels : [0, 0, 0, 0, 0], | ||||
|             datasets : [ | ||||
|                 { | ||||
|                     fillColor: "rgba(44,127,184,0.5)", | ||||
|                     strokeColor: "rgba(44,127,184,1)", | ||||
|                     pointColor: "rgba(44,127,184,1)", | ||||
|                     pointStrokeColor: "#fff", | ||||
|                     data: [0, 0, 0, 0, 0] | ||||
|                 } | ||||
|             ] | ||||
|         }; | ||||
|         var diskLineData = { | ||||
|             labels : [0, 0, 0, 0, 0], | ||||
|             datasets : [ | ||||
|                 { | ||||
|                     fillColor: "rgba(127,205,187,0.5)", | ||||
|                     strokeColor: "rgba(127,205,187,1)", | ||||
|                     pointColor: "rgba(127,205,187,1)", | ||||
|                     pointStrokeColor: "#fff", | ||||
|                     data: [0, 0, 0, 0, 0], | ||||
|                     label: "Read" | ||||
|                 }, | ||||
|                 { | ||||
|                     fillColor: "rgba(44,127,184,0.5)", | ||||
|                     strokeColor: "rgba(44,127,184,1)", | ||||
|                     pointColor: "rgba(44,127,184,1)", | ||||
|                     pointStrokeColor: "#fff", | ||||
|                     data: [0, 0, 0, 0, 0], | ||||
|                     label: "Write" | ||||
|                 }, | ||||
|             ] | ||||
|         }; | ||||
|         var netLineData = { | ||||
|             labels : [0, 0, 0, 0, 0], | ||||
|             datasets : [ | ||||
|                { | ||||
|                     fillColor: "rgba(127,205,187,0.5)", | ||||
|                     strokeColor: "rgba(127,205,187,1)", | ||||
|                     pointColor: "rgba(127,205,187,1)", | ||||
|                     pointStrokeColor: "#fff", | ||||
|                     data: [0, 0, 0, 0, 0], | ||||
|                     label: "Inbound" | ||||
|                }, | ||||
|                { | ||||
|                     fillColor: "rgba(44,127,184,0.5)", | ||||
|                     strokeColor: "rgba(44,127,184,1)", | ||||
|                     pointColor: "rgba(44,127,184,1)", | ||||
|                     pointStrokeColor: "#fff", | ||||
|                     data: [0, 0, 0, 0, 0], | ||||
|                     label: "Outbound" | ||||
|                }, | ||||
|             ] | ||||
|         }; | ||||
|         var cpuOpt = { | ||||
|             animation: false, | ||||
|             pointDotRadius: 2, | ||||
|             scaleLabel: "<%=value%> %", | ||||
|             tooltipTemplate: "<%=value%> %", | ||||
|             scaleShowGridLines : false, | ||||
|             scaleOverride: true, | ||||
|             scaleSteps: 5, | ||||
|             scaleStepWidth: 20, | ||||
|             scaleStartValue: 0, | ||||
|             responsive: true | ||||
|         }; | ||||
|         var diskOpt = { | ||||
|             animation: false, | ||||
|             pointDotRadius: 2, | ||||
|             scaleLabel: "<%=value%> Mb/s", | ||||
|             multiTooltipTemplate: "<%=datasetLabel%> - <%=value%> Mb/s", | ||||
|             scaleShowGridLines : false, | ||||
|             responsive: true | ||||
|         }; | ||||
|         var netOpt = { | ||||
|             animation: false, | ||||
|             pointDotRadius: 2, | ||||
|             scaleLabel: "<%=value%> Mbps", | ||||
|             multiTooltipTemplate: "<%=datasetLabel%> - <%=value%> Mbps", | ||||
|             scaleShowGridLines : false, | ||||
|             responsive: true, | ||||
|         }; | ||||
| 
 | ||||
|         var cpu_ctx = $("#cpuChart").get(0).getContext("2d"); | ||||
|         var cpuChart = new Chart(cpu_ctx).Line(cpuLineData, cpuOpt); | ||||
|         var cpuChart = new Chart(cpu_ctx, { | ||||
|             type: 'line', | ||||
|             data: { | ||||
|                 datasets : [{ | ||||
|                     backgroundColor: "rgba(44,127,184,0.5)", | ||||
|                     label: "Usage" | ||||
|                 }] | ||||
|             }, | ||||
|             options: { | ||||
|                 responsive: true, | ||||
|                 legend: { | ||||
|                     display: false | ||||
|                 }, | ||||
|                 scales: { | ||||
|                     xAxes:[{ | ||||
|                         offset: false, | ||||
|                         ticks: { | ||||
|                             beginAtZero: false, | ||||
|                             autoSkip: true, | ||||
|                             maxTicksLimit: 10, | ||||
|                             maxRotation: 0, | ||||
|                             minRotation: 0, | ||||
|                             stepSize: 10, | ||||
|                         }, | ||||
|                     }], | ||||
|                     yAxes: [{ | ||||
|                         ticks: { | ||||
|                             suggestedMax: 100, | ||||
|                             suggestedMin: 0, | ||||
|                             stepSize: 20, | ||||
|                             callback: function(value, index, values) { | ||||
|                                 return value + ' %'; | ||||
|                             } | ||||
|                         }, | ||||
|                     }], | ||||
|                 }, | ||||
|                 tooltips: { | ||||
|                      callbacks: { | ||||
|                          label: function (tooltipItem, chart) { | ||||
|                              var label = chart.datasets[tooltipItem.datasetIndex].label || ''; | ||||
|                              if (label) { | ||||
|                                 label += ': '; | ||||
|                              } | ||||
|                              return label += tooltipItem.yLabel + ' %'; | ||||
|                          } | ||||
|                      } | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         var mem_ctx = $("#memChart").get(0).getContext("2d"); | ||||
|         var memChart = new Chart(mem_ctx, { | ||||
|             type: 'line', | ||||
|             data: { | ||||
|                 datasets : [{ | ||||
|                     label: "Usage" | ||||
|                 }] | ||||
|             }, | ||||
|             options: { | ||||
|                 responsive: true, | ||||
|                 legend: { | ||||
|                     display: false | ||||
|                 }, | ||||
|                 scales: { | ||||
|                     xAxes:[{ | ||||
|                         offset: false, | ||||
|                         ticks: { | ||||
|                             beginAtZero: false, | ||||
|                             autoSkip: true, | ||||
|                             maxTicksLimit: 10, | ||||
|                             maxRotation: 0, | ||||
|                             minRotation: 0, | ||||
|                             stepSize: 10, | ||||
|                         }, | ||||
|                     }], | ||||
|                     yAxes: [{ | ||||
|                         ticks: { | ||||
|                             suggestedMax: 100, | ||||
|                             suggestedMin: 0, | ||||
|                             stepSize: 20, | ||||
|                             callback: function(value, index, values) { | ||||
|                                 return value + ' MB'; | ||||
|                             } | ||||
|                         }, | ||||
|                     }], | ||||
|                 }, | ||||
|                 tooltips: { | ||||
|                      callbacks: { | ||||
|                          label: function (tooltipItem, chart) { | ||||
|                              var label = chart.datasets[tooltipItem.datasetIndex].label || ''; | ||||
|                              if (label) { | ||||
|                                 label += '(RSS): '; | ||||
|                              } | ||||
|                              return label += tooltipItem.yLabel + ' MB'; | ||||
|                          } | ||||
|                      } | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         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); | ||||
|             diskChart['{{ disk.dev }}'] = new Chart(disk_ctx_{{ disk.dev }}, { | ||||
|                 type: 'line', | ||||
|                 data: { | ||||
|                     datasets : [{ | ||||
|                         backgroundColor: "rgba(127,205,187,0.5)", | ||||
|                         label: "Read" | ||||
|                     }, | ||||
|                     { | ||||
|                         backgroundColor: "rgba(44,127,184,0.5)", | ||||
|                         label: "Write" | ||||
|                     }] | ||||
|                 }, | ||||
|                 options: { | ||||
|                     responsive: true, | ||||
|                     legend: { | ||||
|                         display: false | ||||
|                     }, | ||||
|                     scales: { | ||||
|                         xAxes:[{ | ||||
|                             offset: false, | ||||
|                             ticks: { | ||||
|                                 beginAtZero: false, | ||||
|                                 autoSkip: true, | ||||
|                                 maxTicksLimit: 10, | ||||
|                                 maxRotation: 0, | ||||
|                                 minRotation: 0, | ||||
|                                 stepSize: 10, | ||||
|                             }, | ||||
|                         }], | ||||
|                         yAxes: [{ | ||||
|                             ticks: { | ||||
|                                 suggestedmax: 100, | ||||
|                                 suggestedMin: 0, | ||||
|                                 callback: function(value, index, values) { | ||||
|                                     return value + ' Mb/s'; | ||||
|                                 } | ||||
|                             }, | ||||
|                         }], | ||||
|                     }, | ||||
|                     tooltips: { | ||||
|                          callbacks: { | ||||
|                              label: function (tooltipItem, chart) { | ||||
|                                  var label = chart.datasets[tooltipItem.datasetIndex].label || ''; | ||||
|                                  if (label) { | ||||
|                                     label += ': '; | ||||
|                                  } | ||||
|                                  return label += tooltipItem.yLabel + ' Mb/s'; | ||||
|                              } | ||||
|                          } | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|         {% 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); | ||||
|             netChart['{{ forloop.counter0 }}'] = new Chart(net_ctx_{{ forloop.counter0 }}, { | ||||
|                 type: 'line', | ||||
|                 data: { | ||||
|                    datasets : [ | ||||
|                        { | ||||
|                             backgroundColor: "rgba(127,205,187,0.5)", | ||||
|                             label: "Inbound" | ||||
|                        }, | ||||
|                        { | ||||
|                             backgroundColor: "rgba(44,127,184,0.5)", | ||||
|                             label: "Outbound" | ||||
|                        }] | ||||
|                 }, | ||||
|                 options: { | ||||
|                     responsive: true, | ||||
|                     legend: { | ||||
|                         display: false | ||||
|                     }, | ||||
|                     scales: { | ||||
|                         xAxes:[{ | ||||
|                             offset: false, | ||||
|                             ticks: { | ||||
|                                 beginAtZero: false, | ||||
|                                 autoSkip: true, | ||||
|                                 maxTicksLimit: 10, | ||||
|                                 maxRotation: 0, | ||||
|                                 minRotation: 0, | ||||
|                                 stepSize: 10, | ||||
|                             }, | ||||
|                         }], | ||||
|                         yAxes: [{ | ||||
|                             ticks: { | ||||
|                                 suggestedMax: 100, | ||||
|                                 suggestedMin: 0, | ||||
|                                 callback: function(value, index, values) { | ||||
|                                     return value + ' Mbps'; | ||||
|                                 } | ||||
|                             }, | ||||
|                         }], | ||||
|                     }, | ||||
|                     tooltips: { | ||||
|                          callbacks: { | ||||
|                              label: function (tooltipItem, chart) { | ||||
|                                  var label = chart.datasets[tooltipItem.datasetIndex].label || ''; | ||||
|                                  if (label) { | ||||
|                                     label += ': '; | ||||
|                                  } | ||||
|                                  return label += tooltipItem.yLabel + ' Mbps'; | ||||
|                              } | ||||
|                          } | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|         {% endfor %} | ||||
| 
 | ||||
|         window.setInterval(function graph_usage() { | ||||
|             $.getJSON('{% url 'inst_graph' compute_id vname %}', function (data) { | ||||
|                 cpuChart.scale.xLabels = data.timeline; | ||||
|                 for (var i = 0; i < data.cpudata.length; i++) { | ||||
|                     cpuChart.datasets[0].points[i].value = data.cpudata[i]; | ||||
| 
 | ||||
|                 cpuChart.data.labels.push(data.timeline); | ||||
| 
 | ||||
|                 cpuChart.data.datasets[0].data.push(data.cpudata); | ||||
|                 if (cpuChart.data.datasets[0].data.length > 10){ | ||||
|                     cpuChart.data.labels.shift(); | ||||
|                     cpuChart.data.datasets[0].data.shift(); | ||||
|                 } | ||||
|                 cpuChart.update(); | ||||
| 
 | ||||
|                 for (var j = 0; j < data.blkdata.length; j++) { | ||||
|                     diskChart[data.blkdata[j].dev].scale.xLabels = data.timeline; | ||||
|                 memChart.data.labels.push(data.timeline); | ||||
| 
 | ||||
|                     for (var i = 0; i < data.blkdata[j].data[0].length; i++) { | ||||
|                         diskChart[data.blkdata[j].dev].datasets[0].points[i].label = 'Time: ' + data.timeline[i]; | ||||
|                         diskChart[data.blkdata[j].dev].datasets[0].points[i].value = data.blkdata[j].data[0][i]; | ||||
|                         diskChart[data.blkdata[j].dev].datasets[1].points[i].value = data.blkdata[j].data[1][i]; | ||||
| 
 | ||||
|                 memChart.options.scales.yAxes[0].ticks.max = parseInt(data.memdata.total / 1024); | ||||
|                 memChart.options.scales.yAxes[0].ticks.stepSize = parseInt(data.memdata.total / (1024 * 5)); | ||||
|                 memChart.data.datasets[0].data.push(data.memdata.used / 1024); | ||||
|                 if (memChart.data.datasets[0].data.length > 10){ | ||||
|                     memChart.data.labels.shift(); | ||||
|                     memChart.data.datasets[0].data.shift(); | ||||
|                 } | ||||
|                 memChart.update(); | ||||
| 
 | ||||
| 
 | ||||
|                 for (let j = 0; j < data.blkdata.length; j++) { | ||||
|                     diskChart[data.blkdata[j].dev].data.labels.push(data.timeline); | ||||
| 
 | ||||
|                     diskChart[data.blkdata[j].dev].data.datasets[0].data.push(data.blkdata[0].data[0]); | ||||
|                     diskChart[data.blkdata[j].dev].data.datasets[1].data.push(data.blkdata[0].data[1]); | ||||
|                     if (diskChart[data.blkdata[j].dev].data.datasets[0].data.length > 10){ | ||||
|                         diskChart[data.blkdata[j].dev].data.labels.shift(); | ||||
|                         diskChart[data.blkdata[j].dev].data.datasets[0].data.shift(); | ||||
|                         diskChart[data.blkdata[j].dev].data.datasets[1].data.shift(); | ||||
|                     } | ||||
| 
 | ||||
|                     diskChart[data.blkdata[j].dev].update(); | ||||
|                 } | ||||
| 
 | ||||
|                 for (var j = 0; j < data.netdata.length; j++) { | ||||
|                     netChart[data.netdata[j].dev].scale.xLabels = data.timeline; | ||||
|                 for (let j = 0; j < data.netdata.length; j++) { | ||||
|                     netChart[data.netdata[j].dev].data.labels.push(data.timeline); | ||||
| 
 | ||||
|                     for (var i = 0; i < data.netdata[j].data[0].length; i++) { | ||||
|                         netChart[data.netdata[j].dev].datasets[0].points[i].label = 'Time: ' + data.timeline[i]; | ||||
|                         netChart[data.netdata[j].dev].datasets[0].points[i].value = data.netdata[j].data[0][i]; | ||||
|                         netChart[data.netdata[j].dev].datasets[1].points[i].value = data.netdata[j].data[1][i]; | ||||
|                     netChart[data.netdata[j].dev].data.datasets[0].data.push(data.netdata[0].data[0]); | ||||
|                     netChart[data.netdata[j].dev].data.datasets[1].data.push(data.netdata[0].data[1]); | ||||
|                     if (netChart[data.netdata[j].dev].data.datasets[0].data.length > 10){ | ||||
|                         netChart[data.netdata[j].dev].data.labels.shift(); | ||||
|                         netChart[data.netdata[j].dev].data.datasets[0].data.shift(); | ||||
|                         netChart[data.netdata[j].dev].data.datasets[1].data.shift(); | ||||
|                     } | ||||
| 
 | ||||
|                     netChart[data.netdata[j].dev].update(); | ||||
|                 } | ||||
|             }); | ||||
|  |  | |||
|  | @ -1040,24 +1040,13 @@ def inst_graph(request, compute_id, vname): | |||
|     :param request: | ||||
|     :return: | ||||
|     """ | ||||
| 
 | ||||
|     datasets = {} | ||||
|     json_blk = [] | ||||
|     datasets_blk = {} | ||||
|     json_net = [] | ||||
|     datasets_net = {} | ||||
|     cookies = {} | ||||
|     points = 5 | ||||
|     current_time = time.strftime("%H:%M:%S") | ||||
| 
 | ||||
|     compute = get_object_or_404(Compute, pk=compute_id) | ||||
|     response = HttpResponse() | ||||
|     response['Content-Type'] = "text/javascript" | ||||
| 
 | ||||
|     def check_points(dataset): | ||||
|         if len(dataset) > points: | ||||
|             dataset.pop(0) | ||||
|         return dataset | ||||
| 
 | ||||
|     try: | ||||
|         conn = wvmInstance(compute.hostname, | ||||
|                            compute.login, | ||||
|  | @ -1065,71 +1054,24 @@ def inst_graph(request, compute_id, vname): | |||
|                            compute.type, | ||||
|                            vname) | ||||
|         cpu_usage = conn.cpu_usage() | ||||
|         mem_usage = conn.mem_usage() | ||||
|         blk_usage = conn.disk_usage() | ||||
|         net_usage = conn.net_usage() | ||||
|         conn.close() | ||||
| 
 | ||||
|         try: | ||||
|             cookies['cpu'] = request.COOKIES['cpu'] | ||||
|             cookies['blk'] = request.COOKIES['blk'] | ||||
|             cookies['net'] = request.COOKIES['net'] | ||||
|             cookies['timer'] = request.COOKIES['timer'] | ||||
|         except KeyError: | ||||
|             cookies['cpu'] = cookies['blk'] = cookies['net'] = None | ||||
| 
 | ||||
|         if not cookies['cpu']: | ||||
|             datasets['timer'] = datasets['cpu'] = [0] * points | ||||
|         else: | ||||
|             datasets['cpu'] = eval(cookies['cpu']) | ||||
|             datasets['timer'] = eval(cookies['timer']) | ||||
| 
 | ||||
|         datasets['timer'].append(current_time) | ||||
|         datasets['cpu'].append(int(cpu_usage['cpu'])) | ||||
| 
 | ||||
|         datasets['timer'] = check_points(datasets['timer']) | ||||
|         datasets['cpu'] = check_points(datasets['cpu']) | ||||
| 
 | ||||
|         current_time = time.strftime("%H:%M:%S") | ||||
|         for blk in blk_usage: | ||||
|             if not cookies['blk']: | ||||
|                 datasets_rd = datasets_wr = [0] * points | ||||
|             else: | ||||
|                 datasets['blk'] = eval(cookies['blk']) | ||||
|                 datasets_rd = datasets['blk'][blk['dev']][0] | ||||
|                 datasets_wr = datasets['blk'][blk['dev']][1] | ||||
| 
 | ||||
|                 datasets_rd.append(int(blk['rd']) / 1048576) | ||||
|                 datasets_wr.append(int(blk['wr']) / 1048576) | ||||
| 
 | ||||
|                 datasets_rd = check_points(datasets_rd) | ||||
|                 datasets_wr = check_points(datasets_wr) | ||||
| 
 | ||||
|             json_blk.append({'dev': blk['dev'], 'data': [datasets_rd, datasets_wr]}) | ||||
|             datasets_blk[blk['dev']] = [datasets_rd, datasets_wr] | ||||
|             json_blk.append({'dev': blk['dev'], 'data': [int(blk['rd']) / 1048576, int(blk['wr']) / 1048576]}) | ||||
| 
 | ||||
|         for net in net_usage: | ||||
|             if not cookies['net']: | ||||
|                 datasets_tx = datasets_rx = [0] * points | ||||
|             else: | ||||
|                 datasets['net'] = eval(cookies['net']) | ||||
|                 datasets_rx = datasets['net'][net['dev']][0] | ||||
|                 datasets_tx = datasets['net'][net['dev']][1] | ||||
|             json_net.append({'dev': net['dev'], 'data': [int(net['rx']) / 1048576, int(net['tx']) / 1048576]}) | ||||
| 
 | ||||
|                 datasets_rx.append(int(net['rx']) / 1048576) | ||||
|                 datasets_tx.append(int(net['tx']) / 1048576) | ||||
|         data = json.dumps({'cpudata': int(cpu_usage['cpu']), | ||||
|                            'memdata': mem_usage, | ||||
|                            'blkdata': json_blk, | ||||
|                            'netdata': json_net, | ||||
|                            'timeline': current_time}) | ||||
| 
 | ||||
|                 datasets_rx = check_points(datasets_rx) | ||||
|                 datasets_tx = check_points(datasets_tx) | ||||
| 
 | ||||
|             json_net.append({'dev': net['dev'], 'data': [datasets_rx, datasets_tx]}) | ||||
|             datasets_net[net['dev']] = [datasets_rx, datasets_tx] | ||||
| 
 | ||||
|         data = json.dumps({'cpudata': datasets['cpu'], 'blkdata': json_blk, | ||||
|                            'netdata': json_net, 'timeline': datasets['timer']}) | ||||
| 
 | ||||
|         response.cookies['cpu'] = datasets['cpu'] | ||||
|         response.cookies['timer'] = datasets['timer'] | ||||
|         response.cookies['blk'] = datasets_blk | ||||
|         response.cookies['net'] = datasets_net | ||||
|     except libvirtError: | ||||
|         data = json.dumps({'error': 'Error 500'}) | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue