diff --git a/src/sunstone/bin/sunstone-server b/src/sunstone/bin/sunstone-server
index e7b505ac42..6ecf6bb9c4 100755
--- a/src/sunstone/bin/sunstone-server
+++ b/src/sunstone/bin/sunstone-server
@@ -23,12 +23,18 @@ if [ -z "$ONE_LOCATION" ]; then
SUNSTONE_LOCK_FILE=/var/lock/one/.sunstone.lock
SUNSTONE_LOG=/var/log/one/sunstone.log
SUNSTONE_CONF=/etc/one/sunstone-server.conf
+ ONEMONITOR_CMD=/usr/lib/one/sunstone/share/OneMonitor/runOneMonitor.sh
+ HOST_LOG_FOLDER=/var/log/one/OneMonitor/host
+ VM_LOG_FOLDER=/var/log/one/OneMonitor/vm
else
SUNSTONE_PID=$ONE_LOCATION/var/sunstone.pid
SUNSTONE_SERVER=$ONE_LOCATION/lib/sunstone/config.ru
SUNSTONE_LOCK_FILE=$ONE_LOCATION/var/.sunstone.lock
SUNSTONE_LOG=$ONE_LOCATION/var/sunstone.log
SUNSTONE_CONF=$ONE_LOCATION/etc/sunstone-server.conf
+ ONEMONITOR_CMD=$ONE_LOCATION/lib/sunstone/share/OneMonitor/runOneMonitor.sh
+ HOST_LOG_FOLDER=$ONE_LOCATION/var/OneMonitor/host
+ VM_LOG_FOLDER=$ONE_LOCATION/var/OneMonitor/vm
fi
setup()
@@ -84,6 +90,24 @@ start()
fi
echo "sunstone-server listening on $HOST:$PORT"
+
+ # Start the monitoring app
+ if [ ! -d $HOST_LOG_FOLDER ]
+ then
+ mkdir -p $HOST_LOG_FOLDER
+ [[ $? -ne 0 ]] && ( echo "Error creating host log directory"; exit 1 )
+ fi
+
+ if [ ! -d $VM_LOG_FOLDER ]
+ then
+ mkdir -p $VM_LOG_FOLDER
+ [[ $? -ne 0 ]] && ( echo "Error creating vm log directory"; exit 1 )
+ fi
+
+ $ONEMONITOR_CMD $MONITORING_INTERVAL $HOST_LOG_FOLDER $VM_LOG_FOLDER &>/dev/null &
+
+ [[ $? -ne 0 ]] && ( echo "Error launching monitoring daemon"; exit 1 )
+
}
#
@@ -102,6 +126,8 @@ stop()
# Remove pid files
rm -f $SUNSTONE_LOCK_FILE &> /dev/null
+ killall $ONEMONITOR_CMD
+
echo "sunstone-server stopped"
}
diff --git a/src/sunstone/models/SunstoneServer.rb b/src/sunstone/models/SunstoneServer.rb
index 509d053c86..9c1198fe21 100644
--- a/src/sunstone/models/SunstoneServer.rb
+++ b/src/sunstone/models/SunstoneServer.rb
@@ -17,6 +17,8 @@
require 'OpenNebulaJSON'
include OpenNebulaJSON
+require 'OneMonitorClient'
+
class SunstoneServer
def initialize(username, password)
# TBD one_client_user(name) from CloudServer
@@ -265,60 +267,22 @@ class SunstoneServer
#
############################################################################
- def get_log(resource,id,config,monitor_resources,history_length)
- log_file_prefix = case resource
- when "vm","VM"
- config[:host_log_file]
- when "host","HOST"
- config[:vm_log_file]
- end
+ def get_log(params)
+ resource = params[:resource]
+ id = params[:id]
+ id = "global" unless id
+ columns = params['monitor_resources'].split(',')
+ history_length = params['history_length']
- if !log_file_prefix or log_file_prefix.empty?
- log_file_prefix = "/srv/cloud/one-dummy/logs/"+resource
- end
+ log_file_folder = case resource
+ when "vm","VM"
+ VM_LOG_FOLDER
+ when "host","HOST"
+ HOST_LOG_FOLDER
+ end
- log_file = "#{log_file_prefix}_#{id}.csv"
-
- first_line = `head -1 #{log_file}`.chomp
-
- if $?.exitstatus != 0
- error = Error.new("Cannot open log file")
- return [500, error.to_json]
- end
-
- n_lines = `wc -l #{log_file} | cut -d' ' -f 1`.to_i
- if n_lines <= history_length.to_i
- history_length = n_lines-1
- end
-
- fields = first_line.split(',')
- poll_time_pos = fields.index("time")
- id_pos = fields.index("id")
-
- if !id_pos or !poll_time_pos
- error = Error.new("It seems poll_time or id information cannot be read from log file")
- return [500, error.to_json]
- end
-
- series = [] #will hold several graphs
- tail = `tail -#{history_length} #{log_file}`
-
- monitor_resources.split(',').each do | resource |
-
- graph = []
- resource_pos = fields.index(resource)
-
- tail.each_line do | line |
- line_arr = line.delete('"').split(',')
- if (line_arr[id_pos].to_i == id.to_i)
- graph << [ line_arr[poll_time_pos].to_i*1000, line_arr[resource_pos].to_i ]
- end
- end
-
- series << graph
- end
-
- return series.to_json
+ monitor_client = OneMonitorClient.new(id,log_file_folder)
+ return monitor_client.get_data_for_id(id,columns,history_length).to_json
end
############################################################################
diff --git a/src/sunstone/public/css/application.css b/src/sunstone/public/css/application.css
index d068cbef4a..6840aefa7c 100644
--- a/src/sunstone/public/css/application.css
+++ b/src/sunstone/public/css/application.css
@@ -55,17 +55,16 @@ table#dashboard_table tr {
vertical-align: top;
}
-table#dashboard_table td{
+table#dashboard_table > tbody > tr > td{
width:50%;
}
div.panel {
background-color: #ffffff;
padding:0;
- width:80%;
margin: 10px;
border: 1px #ddd solid;
- min-height: 110px;
+ min-height: 50px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-moz-box-shadow: 5px 5px 5px #888;
@@ -77,6 +76,8 @@ div.panel h3 {
border: 0;
padding:5px 10px 5px 10px;
margin: 0;
+ color: white;
+ font-weight: bold;
background-color: #353735;
-webkit-border-radius: 3px 3px 0 0;
-moz-border-radius: 3px 3px 0 0;
@@ -105,7 +106,7 @@ div.panel_info table.info_table tr {
border: 0;
border-bottom: 1px dotted #ccc;
}
-div.panel_info table.info_table td {
+div.panel_info table.info_table > tbody > tr > td {
border: 0;
width: 100%!important;
}
@@ -114,11 +115,11 @@ div.panel_info table.info_table td.value_td {
text-align: right;
}
-.key_td_green {
+.green {
color: green!important;
}
-.key_td_red {
+.red {
color: #B81515!important;
}
@@ -387,6 +388,12 @@ tr.even:hover{
font-weight:bold;
}
+.info_table td.graph_td{
+ padding-top:0px!important;
+ padding-bottom:0px!important;
+ vertical-align:middle!important;
+}
+
.info_table td.value_td{
text-align:left;
}
diff --git a/src/sunstone/public/js/opennebula.js b/src/sunstone/public/js/opennebula.js
index cc74ec6087..88391d8756 100644
--- a/src/sunstone/public/js/opennebula.js
+++ b/src/sunstone/public/js/opennebula.js
@@ -504,6 +504,37 @@ var OpenNebula = {
}
}
});
+ },
+ "monitor_all" : function(params){
+ var callback = params.success;
+ var callback_error = params.error;
+ var resource = OpenNebula.Host.resource;
+ var data = params.data;
+
+ var method = "monitor";
+ var action = OpenNebula.Helper.action(method);
+ var request = OpenNebula.Helper.request(resource,method, data);
+
+ $.ajax({
+ url: "host/monitor",
+ type: "GET",
+ data: data['monitor'],
+ dataType: "json",
+ success: function(response)
+ {
+ if (callback)
+ {
+ callback(request,response);
+ }
+ },
+ error: function(response)
+ {
+ if (callback_error)
+ {
+ callback_error(request, OpenNebula.Error(response));
+ }
+ }
+ });
}
},
@@ -1369,6 +1400,37 @@ var OpenNebula = {
}
}
});
+ },
+ "monitor_all" : function(params){
+ var callback = params.success;
+ var callback_error = params.error;
+ var resource = OpenNebula.VM.resource;
+ var data = params.data;
+
+ var method = "monitor";
+ var action = OpenNebula.Helper.action(method);
+ var request = OpenNebula.Helper.request(resource,method, data);
+
+ $.ajax({
+ url: "vm/monitor",
+ type: "GET",
+ data: data['monitor'],
+ dataType: "json",
+ success: function(response)
+ {
+ if (callback)
+ {
+ callback(request,response);
+ }
+ },
+ error: function(response)
+ {
+ if (callback_error)
+ {
+ callback_error(request, OpenNebula.Error(response));
+ }
+ }
+ });
}
},
diff --git a/src/sunstone/public/js/plugins/dashboard-tab.js b/src/sunstone/public/js/plugins/dashboard-tab.js
index b6bc6fb2ac..1550a5e092 100644
--- a/src/sunstone/public/js/plugins/dashboard-tab.js
+++ b/src/sunstone/public/js/plugins/dashboard-tab.js
@@ -14,44 +14,81 @@
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
+var HISTORY_LENGTH=40;
+var GRAPH_AUTOREFRESH_INTERVAL=10000; //10 secs
+
+var graph1 = {
+ title : "graph1",
+ monitor_resources : "total,active,error",
+ history_length : HISTORY_LENGTH
+};
+
+var graph2 = {
+ title : "graph2",
+ monitor_resources : "cpu_usage,used_cpu,max_cpu",
+ history_length : HISTORY_LENGTH
+};
+
+var graph3 = {
+ title : "graph3",
+ monitor_resources : "mem_usage,used_mem,max_mem",
+ history_length : HISTORY_LENGTH
+};
+
+var graph4 = {
+ title : "graph4",
+ monitor_resources : "total,active,error",
+ history_length : HISTORY_LENGTH
+};
+
+var graph5 = {
+ title : "graph5",
+ monitor_resources : "net_tx,net_rx",
+ history_length : HISTORY_LENGTH
+};
+
var dashboard_tab_content =
'
\
+\
+\
+\
+ | \
+\
+\
+ \
+ \
\
- Users\
- \
- \
+ Historical monitoring information\
\
- \
+ \
+ Total host count | \
+ | \
+ '+spinner+' | \
+ Hosts CPU | \
+ | \
+ '+spinner+' | \
+ Hosts memory | \
+ | \
+ '+spinner+' | \
+ Total VM count | \
+ | \
+ '+spinner+' | \
+ VM Network stats | \
+ | \
+ '+spinner+' | \
+ \
\
\
| \
\
- ';
-
+ |
\
+\
+';
var dashboard_tab = {
title: 'Dashboard',
@@ -157,6 +166,74 @@ var dashboard_tab = {
Sunstone.addMainTab('dashboard_tab',dashboard_tab);
+function plot_global_graph(data,info){
+ var id = info.title;
+ var labels_arr = info.monitor_resources.split(',');
+ var serie;
+ var series = [];
+ var width = ($(window).width()-129)*45/100;
+
+ $('#'+id).html('');
+
+ for (var i = 0; i< labels_arr.length; i++) {
+ serie = {
+ label: labels_arr[i],
+ data: data[i]
+ };
+ series.push(serie);
+ };
+
+ var options = {
+ legend : { show : true,
+ noColumns: labels_arr.length,
+ container: $('#'+id+'_legend')},
+ xaxis : { mode: "time",
+ timeformat: "%h:%M"
+ },
+ yaxis : { labelWidth: 40 }
+ }
+
+ switch (id){
+ case "graph3":
+ case "graph5":
+ options["yaxis"]["tickFormatter"] = function(val,axis) { return humanize_size(val); }
+ }
+
+
+
+ $.plot($('#'+id+'_graph'),series,options);
+}
+
+function quickstart_setup(){
+
+ $('#quickstart').button("disable");
+
+ $('#quickstart_form input').click(function(){
+ $('#quickstart').val($(this).val());
+ $('#quickstart').button("enable");
+ });
+
+ $('#quickstart').click(function(){
+ Sunstone.runAction($(this).val());
+ return false;
+ });
+}
+
+function graph_autorefresh(){
+ setInterval(function(){
+ refresh_graphs();
+ },GRAPH_AUTOREFRESH_INTERVAL);
+
+}
+
+function refresh_graphs(){
+ Sunstone.runAction("Host.monitor_all", graph1);
+ Sunstone.runAction("Host.monitor_all", graph2);
+ Sunstone.runAction("Host.monitor_all", graph3);
+ Sunstone.runAction("VM.monitor_all", graph4);
+ Sunstone.runAction("VM.monitor_all", graph5);
+}
+
$(document).ready(function(){
//Dashboard link listener
$("#dashboard_table h3 a").live("click", function (){
@@ -164,13 +241,17 @@ $(document).ready(function(){
showTab(tab);
return false;
});
-
+
emptyDashboard();
if (uid!=0) {
$("td.oneadmin").hide();
}
-
-
+
+ quickstart_setup();
+
+ refresh_graphs();
+ graph_autorefresh();
+
});
//puts the dashboard values into "retrieving"
@@ -180,62 +261,73 @@ function emptyDashboard(){
function updateDashboard(what,json_info){
- db = $('#dashboard_tab');
- switch (what){
- case "hosts":
- total_hosts=json_info.length;
- active_hosts=0;
- $.each(json_info,function(){
- if (parseInt(this.HOST.STATE) < 3){
- active_hosts++;}
- });
- $('#total_hosts',db).html(total_hosts);
- $('#active_hosts',db).html(active_hosts);
- break;
- case "clusters":
- total_clusters=json_info.length;
- $('#total_clusters',db).html(total_clusters);
- break;
- case "vms":
- total_vms=json_info.length;
- running_vms=0;
+ var db = $('#dashboard_tab');
+ switch (what){
+ case "hosts":
+ var total_hosts=json_info.length;
+ var active_hosts=0;
+ $.each(json_info,function(){
+ if (parseInt(this.HOST.STATE) < 3){
+ active_hosts++;}
+ });
+ $('#total_hosts',db).html(total_hosts+' / ');
+ $('#active_hosts',db).html(active_hosts);
+ break;
+ case "clusters":
+ var total_clusters=json_info.length;
+ $('#total_clusters',db).html(total_clusters);
+ break;
+ case "vms":
+ var total_vms=json_info.length;
+ var running_vms=0;
failed_vms=0;
- $.each(json_info,function(){
- vm_state = parseInt(this.VM.STATE);
- if (vm_state == 3){
- running_vms++;
- }
- else if (vm_state == 7) {
- failed_vms++;
- }
- });
- $('#total_vms',db).html(total_vms);
- $('#running_vms',db).html(running_vms);
- $('#failed_vms',db).html(failed_vms);
- break;
- case "vnets":
- public_vnets=0;
- total_vnets=json_info.length;
- $.each(json_info,function(){
- if (parseInt(this.VNET.PUBLIC)){
- public_vnets++;}
- });
- $('#total_vnets',db).html(total_vnets);
- $('#public_vnets',db).html(public_vnets);
- break;
- case "users":
- total_users=json_info.length;
- $('#total_users',db).html(total_users);
- break;
- case "images":
- total_images=json_info.length;
- public_images=0;
- $.each(json_info,function(){
- if (parseInt(this.IMAGE.PUBLIC)){
- public_images++;}
- });
- $('#total_images',db).html(total_images);
- $('#public_images',db).html(public_images);
- break;
- }
-}
+ $.each(json_info,function(){
+ vm_state = parseInt(this.VM.STATE);
+ if (vm_state == 3){
+ running_vms++;
+ }
+ else if (vm_state == 7) {
+ failed_vms++;
+ }
+ });
+ $('#total_vms',db).html(total_vms+' / ');
+ $('#running_vms',db).html(running_vms+' / ');
+ $('#failed_vms',db).html(failed_vms);
+ break;
+ case "vnets":
+ var public_vnets=0;
+ var total_vnets=json_info.length;
+ $.each(json_info,function(){
+ if (parseInt(this.VNET.PUBLIC)){
+ public_vnets++;}
+ });
+ $('#total_vnets',db).html(total_vnets+' / ');
+ $('#public_vnets',db).html(public_vnets);
+ break;
+ case "users":
+ var total_users=json_info.length;
+ $('#total_users',db).html(total_users);
+ break;
+ case "images":
+ var total_images=json_info.length;
+ var public_images=0;
+ $.each(json_info,function(){
+ if (parseInt(this.IMAGE.PUBLIC)){
+ public_images++;}
+ });
+ $('#total_images',db).html(total_images+' / ');
+ $('#public_images',db).html(public_images);
+ break;
+ case "templates":
+ var total_templates=json_info.length;
+ var public_templates=0;
+ $.each(json_info,function(){
+ if (parseInt(this.VMTEMPLATE.PUBLIC)){
+ public_templates++;
+ }
+ });
+ $('#total_templates',db).html(total_templates+' / ');
+ $('#public_templates',db).html(public_templates);
+ break;
+ }
+}
\ No newline at end of file
diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js
index b29eb412e3..7673b61885 100644
--- a/src/sunstone/public/js/plugins/hosts-tab.js
+++ b/src/sunstone/public/js/plugins/hosts-tab.js
@@ -231,6 +231,10 @@ var host_actions = {
"Host.monitor_all" : {
type: "monitor_global",
call: OpenNebula.Host.monitor_all,
+ callback: function(req,response) {
+ var info = req.request.data[0].monitor;
+ plot_global_graph(response,info);
+ },
error: onError
},
diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js
index c8e4276f04..c0cfcf95b2 100644
--- a/src/sunstone/public/js/plugins/images-tab.js
+++ b/src/sunstone/public/js/plugins/images-tab.js
@@ -663,13 +663,16 @@ function setupCreateImageDialog(){
//Insert HTML in place
$('#create_image_dialog').html(create_image_tmpl);
+ var height = Math.floor($(window).height()*0.8); //set height to a percentage of the window
+
//Prepare jquery dialog
$('#create_image_dialog').dialog({
- autoOpen: false,
- modal:true,
- width: 520
- });
-
+ autoOpen: false,
+ modal:true,
+ width: 520,
+ height: height
+ });
+
$('#img_tabs').tabs();
$('#create_image_dialog button').button();
$('#img_type option').first().attr("selected","selected");
diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js
index c58dfc76eb..2511b7af2c 100644
--- a/src/sunstone/public/js/plugins/templates-tab.js
+++ b/src/sunstone/public/js/plugins/templates-tab.js
@@ -803,6 +803,7 @@ function updateTemplateSelect(){
//update static selectors:
$('#create_vm_dialog #template_id').html(templates_select);
+ $('#speed_virt').html(templates_select);
}
// Callback to update an element in the dataTable
diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js
index 1e3c594248..65b29f663f 100644
--- a/src/sunstone/public/js/plugins/vms-tab.js
+++ b/src/sunstone/public/js/plugins/vms-tab.js
@@ -44,9 +44,8 @@ var vm_graphs = [
monitor_resources : "net_rx",
humanize_figures : true,
history_length : VM_HISTORY_LENGTH
- },
-
-]
+ }
+];
var vms_tab_content =
'