mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-27 10:50:10 +03:00
Feature #1098: Added user consumption plots to Sunstone. Can be looked at from users tab.
The server part is a temporal solution until this functionality is moved to OCA. (cherry picked from commit ce9c7d63db344937d94d7ca04da6e2a7dfbc7544)
This commit is contained in:
parent
ab4e9f456f
commit
a9ad2f830d
@ -274,7 +274,7 @@ class SunstoneServer < CloudServer
|
||||
Host.new_with_id(id, @client)
|
||||
else
|
||||
error = Error.new("Monitoring not supported for #{resource}")
|
||||
return [200, error.to_json]
|
||||
return [403, error.to_json]
|
||||
end
|
||||
|
||||
meters_a = meters.split(',')
|
||||
@ -294,6 +294,56 @@ class SunstoneServer < CloudServer
|
||||
return [200, meters_h.to_json]
|
||||
end
|
||||
|
||||
|
||||
# this code is meant to be replaced as accouting functionality
|
||||
# is moved to OCA. Filtering by group should perhaps be added then.
|
||||
# returns a { monitoring : meter1 : [[ts1, agg_value],[ts2, agg_value]...]
|
||||
# meter2 : [[ts1, agg_value],[ts2, agg_value]...]}
|
||||
# with this information we can paint historical graphs of usage
|
||||
def get_user_accounting(options)
|
||||
id = options[:id]
|
||||
tstart = options[:start].to_i
|
||||
tend = options[:end].to_i
|
||||
interval = options[:interval].to_i
|
||||
meters = options[:monitor_resources]
|
||||
|
||||
result = {}
|
||||
meters_a = meters.split(',')
|
||||
meters_a.each do | meter |
|
||||
result[meter] = []
|
||||
end
|
||||
|
||||
while tstart < tend
|
||||
acct = @client.call('vmpool.accounting',
|
||||
id.to_i,
|
||||
tstart,
|
||||
tstart+interval)
|
||||
if OpenNebula.is_error?(acct)
|
||||
return [500, Error.new(acct.message).to_json]
|
||||
end
|
||||
|
||||
xml = XMLElement.new
|
||||
xml.initialize_xml(acct, 'HISTORY_RECORDS')
|
||||
acct = xml.to_hash
|
||||
|
||||
meters_a.each do | meter |
|
||||
count = 0
|
||||
if acct['HISTORY_RECORDS']['HISTORY'].class == Array
|
||||
acct['HISTORY_RECORDS']['HISTORY'].each do | record |
|
||||
count += record['VM'][meter].to_i
|
||||
end
|
||||
elsif acct['HISTORY_RECORDS']['HISTORY'].class == Hash
|
||||
count += acct['HISTORY_RECORDS']['HISTORY']['VM'][meter].to_i
|
||||
end
|
||||
result[meter] << [tstart, count]
|
||||
end
|
||||
|
||||
tstart += interval
|
||||
end
|
||||
|
||||
return [200, {:monitoring => result}.to_json]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
############################################################################
|
||||
|
@ -754,6 +754,9 @@ var OpenNebula = {
|
||||
"fetch_template" : function(params){
|
||||
OpenNebula.Action.show(params,OpenNebula.User.resource,"template");
|
||||
},
|
||||
"accounting" : function(params){
|
||||
OpenNebula.Action.monitor(params,OpenNebula.User.resource,false);
|
||||
},
|
||||
"set_quota" : function(params){
|
||||
var action_obj = { quotas : params.data.extra_param };
|
||||
OpenNebula.Action.simple_action(params,OpenNebula.User.resource,"set_quota",action_obj);
|
||||
|
@ -21,6 +21,18 @@ var $create_user_dialog;
|
||||
var $user_quotas_dialog;
|
||||
var $update_pw_dialog;
|
||||
|
||||
var user_acct_graphs = [
|
||||
{ title : tr("CPU"),
|
||||
monitor_resources : "CPU",
|
||||
humanize_figures : false
|
||||
},
|
||||
{ title : tr("Memory"),
|
||||
monitor_resources : "MEMORY",
|
||||
humanize_figures : true
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
var users_tab_content = '\
|
||||
<h2><i class="icon-user"></i> '+tr("Users")+'</h2>\
|
||||
<form id="user_form" action="" action="javascript:alert(\'js error!\');">\
|
||||
@ -347,6 +359,16 @@ var user_actions = {
|
||||
error: onError
|
||||
},
|
||||
|
||||
"User.accounting" : {
|
||||
type: "monitor",
|
||||
call: OpenNebula.User.accounting,
|
||||
callback: function(req,response) {
|
||||
var info = req.request.data[0].monitor;
|
||||
plot_graph(response,'#user_acct_tab','user_acct_', info);
|
||||
},
|
||||
error: onError
|
||||
},
|
||||
|
||||
"User.help" : {
|
||||
type: "custom",
|
||||
call: function() {
|
||||
@ -436,6 +458,10 @@ var user_info_panel = {
|
||||
"user_quotas_tab" : {
|
||||
title: tr("User quotas"),
|
||||
content:""
|
||||
},
|
||||
"user_acct_tab" : {
|
||||
title: tr("Historical usage"),
|
||||
content: ""
|
||||
}
|
||||
};
|
||||
|
||||
@ -640,9 +666,92 @@ function updateUserInfo(request,user){
|
||||
content : quotas_tab_html
|
||||
};
|
||||
|
||||
var acct_tab = {
|
||||
title : tr("Historical usages"),
|
||||
content : '<div><table class="info_table" style="margin-bottom:0">\
|
||||
<tr>\
|
||||
<td class="key_td"><label for="from">From / to</label></td>\
|
||||
<td class="value_td">\
|
||||
<input type="text" id="user_acct_from" name="from"/>\
|
||||
<input type="text" id="user_acct_to" name="to"/>\
|
||||
<button id="user_acct_date_ok"><i class="icon-ok"></i></button>\
|
||||
</td>\
|
||||
</tr>\
|
||||
</table></div>' +
|
||||
generateMonitoringDivs(user_acct_graphs, "user_acct_")
|
||||
};
|
||||
|
||||
Sunstone.updateInfoPanelTab("user_info_panel","user_info_tab",info_tab);
|
||||
Sunstone.updateInfoPanelTab("user_info_panel","user_quotas_tab",quotas_tab);
|
||||
Sunstone.updateInfoPanelTab("user_info_panel","user_acct_tab",acct_tab);
|
||||
Sunstone.popUpInfoPanel("user_info_panel");
|
||||
|
||||
var load_acct = function(start,end){
|
||||
//default start 24 hours ago
|
||||
if (!start) start = Math.floor(new Date().getTime()/1000) - 3600 * 24;
|
||||
//default end now
|
||||
if (!end) end = Math.floor(new Date().getTime()/1000);
|
||||
for (var i=0; i<user_acct_graphs.length; i++){
|
||||
var graph_cfg = user_acct_graphs[i];
|
||||
graph_cfg.start = start
|
||||
graph_cfg.end = end
|
||||
graph_cfg.interval = 60 * 60 //1 hour
|
||||
// If the date range is longer than 24 hours, then show only
|
||||
// date, otherwise show time in the x axis
|
||||
graph_cfg.show_date = (end - start) > (3600 * 24)? true : false;
|
||||
Sunstone.runAction("User.accounting",user_info.ID,graph_cfg);
|
||||
};
|
||||
};
|
||||
|
||||
//Enable datepicker
|
||||
var info_dialog = $('div#user_acct_tab');
|
||||
$("#user_acct_from", info_dialog).datepicker({
|
||||
defaultDate: "-1d",
|
||||
changeMonth: true,
|
||||
numberOfMonths: 1,
|
||||
dateFormat: "dd/mm/yy",
|
||||
onSelect: function( selectedDate ) {
|
||||
$( "#user_acct_to", info_dialog).datepicker("option",
|
||||
"minDate",
|
||||
selectedDate );
|
||||
}
|
||||
});
|
||||
|
||||
$("#user_acct_to", info_dialog).datepicker({
|
||||
defaultDate: "0",
|
||||
changeMonth: true,
|
||||
numberOfMonths: 1,
|
||||
dateFormat: "dd/mm/yy",
|
||||
onSelect: function( selectedDate ) {
|
||||
$( "#user_acct_from", info_dialog).datepicker( "option",
|
||||
"maxDate",
|
||||
selectedDate );
|
||||
}
|
||||
});
|
||||
|
||||
//Listen to set date button
|
||||
$('button#user_acct_date_ok', info_dialog).click(function(){
|
||||
var from = $("#user_acct_from", info_dialog).val();
|
||||
var to = $("#user_acct_to", info_dialog).val();
|
||||
|
||||
var start = $.datepicker.parseDate('dd/mm/yy', from)
|
||||
if (start){
|
||||
start = start.getTime();
|
||||
start = Math.floor(start / 1000);
|
||||
}
|
||||
|
||||
var end = $.datepicker.parseDate('dd/mm/yy', to);
|
||||
if (end){
|
||||
end = end.getTime();
|
||||
end = Math.floor(end / 1000);
|
||||
}
|
||||
|
||||
load_acct(start,end);
|
||||
return false;
|
||||
});
|
||||
|
||||
//preload acct
|
||||
load_acct();
|
||||
};
|
||||
|
||||
// Prepare the user creation dialog
|
||||
|
@ -633,6 +633,10 @@ var vm_info_panel = {
|
||||
"vm_history_tab" : {
|
||||
title: tr("History information"),
|
||||
content: ""
|
||||
},
|
||||
"vm_monitoring_tab" : {
|
||||
title: tr("Monitoring information"),
|
||||
content: ""
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -47,7 +47,8 @@ function pretty_time(time_seconds)
|
||||
}
|
||||
|
||||
// Format time for plot axis
|
||||
function pretty_time_axis(time){
|
||||
// If show date, only date information is shown
|
||||
function pretty_time_axis(time, show_date){
|
||||
var d = new Date();
|
||||
d.setTime(time*1000);
|
||||
|
||||
@ -58,7 +59,10 @@ function pretty_time_axis(time){
|
||||
var month = pad(d.getMonth()+1,2); //getMonths returns 0-11
|
||||
var year = d.getFullYear();
|
||||
|
||||
return hour + ":" + mins + ":" + secs;// + " " + month + "/" + day;
|
||||
if (show_date)
|
||||
return month + "/" + day;
|
||||
else
|
||||
return hour + ":" + mins;
|
||||
}
|
||||
|
||||
function pretty_time_runtime(time){
|
||||
@ -660,6 +664,7 @@ function plot_graph(data,context,id_prefix,info){
|
||||
var series = [];
|
||||
var serie;
|
||||
var mon_count = 0;
|
||||
var show_date = info.show_date;
|
||||
|
||||
//make sure series are painted in the order of the
|
||||
//labels array.
|
||||
@ -683,7 +688,7 @@ function plot_graph(data,context,id_prefix,info){
|
||||
},
|
||||
xaxis : {
|
||||
tickFormatter: function(val,axis){
|
||||
return pretty_time_axis(val);
|
||||
return pretty_time_axis(val, show_date);
|
||||
}
|
||||
},
|
||||
yaxis : { labelWidth: 40,
|
||||
|
@ -309,6 +309,10 @@ get '/:resource/monitor' do
|
||||
params[:monitor_resources])
|
||||
end
|
||||
|
||||
get '/user/:id/monitor' do
|
||||
@SunstoneServer.get_user_accounting(params)
|
||||
end
|
||||
|
||||
get '/:resource/:id/monitor' do
|
||||
@SunstoneServer.get_resource_monitoring(
|
||||
params[:id],
|
||||
|
Loading…
x
Reference in New Issue
Block a user