1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-08 21:17:43 +03:00

Feature #3264: calculate-showback uses month,year

And lots of bugs fixed
This commit is contained in:
Carlos Martín 2014-11-06 18:15:29 +01:00
parent 8198887ca2
commit a5aa72359a
6 changed files with 154 additions and 47 deletions

View File

@ -286,14 +286,20 @@ public:
/** /**
* Processes all the history records, and stores the monthly cost for each * Processes all the history records, and stores the monthly cost for each
* VM * VM
* @param start_time Time to start processing. This date will be reset to * @param start_month First month (+year) to process. January is 1.
* the first day of the month, at 00:00 * Use -1 to unset
* @param end_time Time to stop processing. The data will actually be * @param start_year First year (+month) to process. e.g. 2014.
* processed up to the month before this date. * Use -1 to unset
* @param end_month Last month (+year) to process. January is 1.
* Use -1 to unset
* @param end_year Last year (+month) to process. e.g. 2014.
* Use -1 to unset
*/ */
void calculate_showback( void calculate_showback(
time_t start_time, int start_month,
time_t end_time); int start_year,
int end_month,
int end_year);
private: private:
/** /**

View File

@ -187,7 +187,7 @@ class AcctHelper < OpenNebulaHelper::OneHelper
d["YEAR"] d["YEAR"]
end end
column :HOURS, "Hours", :size=>5 do |d| column :HOURS, "Hours", :size=>6 do |d|
d["HOURS"] d["HOURS"]
end end

View File

@ -857,10 +857,25 @@ cmd=CommandParser::CmdParser.new(ARGV) do
command :"calculate-showback", calculate_showback_desc, :options => command :"calculate-showback", calculate_showback_desc, :options =>
[START_TIME, END_TIME] do [START_TIME, END_TIME] do
start_time = options[:start_time] ? options[:start_time].to_i : -1 start_month = -1
end_time = options[:end_time] ? options[:end_time].to_i : -1 start_year = -1
rc = OpenNebula::VirtualMachinePool.new(helper.client).calculate_showback(start_time, end_time) if (options[:start_time])
start_month = options[:start_time].month
start_year = options[:start_time].year
end
end_month = -1
end_year = -1
if (options[:end_time])
end_month = options[:end_time].month
end_year = options[:end_time].year
end
rc = OpenNebula::VirtualMachinePool.new(helper.client).
calculate_showback(start_month, start_year, end_month, end_year)
if OpenNebula.is_error?(rc) if OpenNebula.is_error?(rc)
warn rc.message warn rc.message

View File

@ -167,18 +167,22 @@ module OpenNebula
# Processes all the history records, and stores the monthly cost for # Processes all the history records, and stores the monthly cost for
# each VM # each VM
# #
# @param [Integer] # @param [Integer] start_month First month (+year) to process. January is 1.
# @param [Integer] start_time Time to start processing. This date will # Use -1 to unset
# be reset to the first day of the month, at 00:00 # @param [Integer] start_year First year (+month) to process. e.g. 2014.
# @param [Integer] end_time Time to stop processing. The data will # Use -1 to unset
# actually be processed up to the month before this date. # @param [Integer] end_month Last month (+year) to process. January is 1.
def calculate_showback(start_time, end_time) # Use -1 to unset
start_time ||= -1 # @param [Integer] end_year Last year (+month) to process. e.g. 2014.
end_time ||= -1 # Use -1 to unset
def calculate_showback(start_month, start_year, end_month, end_year)
start_month ||= -1
start_year ||= -1
end_month ||= -1
end_year ||= -1
return @client.call(VM_POOL_METHODS[:calculate_showback], return @client.call(VM_POOL_METHODS[:calculate_showback],
start_time, start_month, start_year, end_month, end_year)
end_time)
end end
# Retrieves the accounting data for all the VMs in the pool # Retrieves the accounting data for all the VMs in the pool

View File

@ -2224,8 +2224,10 @@ void VirtualMachinePoolCalculateShowback::request_execute(
xmlrpc_c::paramList const& paramList, xmlrpc_c::paramList const& paramList,
RequestAttributes& att) RequestAttributes& att)
{ {
int time_start = xmlrpc_c::value_int(paramList.getInt(1)); int start_month = xmlrpc_c::value_int(paramList.getInt(1));
int time_end = xmlrpc_c::value_int(paramList.getInt(2)); int start_year = xmlrpc_c::value_int(paramList.getInt(2));
int end_month = xmlrpc_c::value_int(paramList.getInt(3));
int end_year = xmlrpc_c::value_int(paramList.getInt(4));
ostringstream oss; ostringstream oss;
string where; string where;
@ -2240,7 +2242,8 @@ void VirtualMachinePoolCalculateShowback::request_execute(
return; return;
} }
(static_cast<VirtualMachinePool *>(pool))->calculate_showback(time_start, time_end); (static_cast<VirtualMachinePool *>(pool))->calculate_showback(
start_month, start_year, end_month, end_year);
// TODO: return value? // TODO: return value?
success_response("", att); success_response("", att);

View File

@ -472,7 +472,31 @@ int VirtualMachinePool::min_stime_cb(void * _min_stime, int num, char **values,
return 0; return 0;
} }
void VirtualMachinePool::calculate_showback(time_t start_time, time_t end_time) // TODO: DEBUG
//==============================================================================
string put_time(tm tmp_tm)
{
ostringstream oss;
oss << tmp_tm.tm_mday << "/" << tmp_tm.tm_mon+1 << "/" << tmp_tm.tm_year+1900
<< " " << tmp_tm.tm_hour << ":" << tmp_tm.tm_min << ":" << tmp_tm.tm_sec;
return oss.str();
}
string put_time(time_t t)
{
tm tmp_tm = *localtime(&t);
return put_time(tmp_tm);
}
//==============================================================================
void VirtualMachinePool::calculate_showback(
int start_month,
int start_year,
int end_month,
int end_year)
{ {
vector<xmlNodePtr> nodes; vector<xmlNodePtr> nodes;
vector<xmlNodePtr>::iterator node_it; vector<xmlNodePtr>::iterator node_it;
@ -492,6 +516,7 @@ void VirtualMachinePool::calculate_showback(time_t start_time, time_t end_time)
ostringstream body; ostringstream body;
char * sql_body; char * sql_body;
tm tmp_tm;
int vid; int vid;
int h_stime; int h_stime;
int h_etime; int h_etime;
@ -500,19 +525,33 @@ void VirtualMachinePool::calculate_showback(time_t start_time, time_t end_time)
float cpu; float cpu;
int mem; int mem;
// TODO: debug
//=================================================================
ostringstream debug;
//=================================================================
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Set start and end times for the window to process // Set start and end times for the window to process
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
if (end_time == -1) time_t start_time = time(0);
time_t end_time = time(0);
if (start_month != -1 && start_year != -1)
{ {
end_time = time(0); // First day of the given month
tmp_tm.tm_sec = 0;
tmp_tm.tm_min = 0;
tmp_tm.tm_hour = 0;
tmp_tm.tm_mday = 1;
tmp_tm.tm_mon = start_month - 1;
tmp_tm.tm_year = start_year - 1900;
tmp_tm.tm_isdst = -1;
start_time = mktime(&tmp_tm);
} }
else
if (start_time == -1)
{ {
start_time = time(0);
// Set start time to the lowest stime from the history records // Set start time to the lowest stime from the history records
set_callback(static_cast<Callbackable::Callback>(&VirtualMachinePool::min_stime_cb), set_callback(static_cast<Callbackable::Callback>(&VirtualMachinePool::min_stime_cb),
@ -525,6 +564,25 @@ void VirtualMachinePool::calculate_showback(time_t start_time, time_t end_time)
unset_callback(); unset_callback();
} }
if (end_month != -1 && end_year != -1)
{
// First day of the next month
tmp_tm.tm_sec = 0;
tmp_tm.tm_min = 0;
tmp_tm.tm_hour = 0;
tmp_tm.tm_mday = 1;
tmp_tm.tm_mon = end_month;
tmp_tm.tm_year = end_year - 1900;
tmp_tm.tm_isdst = -1;
time_t end_time_tmp = mktime(&tmp_tm);
if (end_time_tmp < end_time)
{
end_time = end_time_tmp;
}
}
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Get accounting history records // Get accounting history records
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@ -539,12 +597,13 @@ void VirtualMachinePool::calculate_showback(time_t start_time, time_t end_time)
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Reset stime to 1st of month, 00:00 // Reset stime to 1st of month, 00:00
tm tmp_tm = *localtime(&start_time); tmp_tm = *localtime(&start_time);
tmp_tm.tm_sec = 0; tmp_tm.tm_sec = 0;
tmp_tm.tm_min = 0; tmp_tm.tm_min = 0;
tmp_tm.tm_hour = 0; tmp_tm.tm_hour = 0;
tmp_tm.tm_mday = 1; tmp_tm.tm_mday = 1;
tmp_tm.tm_isdst = -1;
time_t tmp_t = mktime(&tmp_tm); time_t tmp_t = mktime(&tmp_tm);
@ -552,10 +611,30 @@ void VirtualMachinePool::calculate_showback(time_t start_time, time_t end_time)
{ {
showback_slots.push_back(tmp_t); showback_slots.push_back(tmp_t);
tmp_tm.tm_sec = 0;
tmp_tm.tm_min = 0;
tmp_tm.tm_hour = 0;
tmp_tm.tm_mday = 1;
tmp_tm.tm_mon++; tmp_tm.tm_mon++;
tmp_tm.tm_isdst = -1;
tmp_t = mktime(&tmp_tm); tmp_t = mktime(&tmp_tm);
} }
// Extra slot that won't be used. Is needed only to calculate the time
// for the second-to-last slot
showback_slots.push_back(end_time);
// TODO: debug
//*=================================================================
for ( slot_it = showback_slots.begin(); slot_it != showback_slots.end(); slot_it++ )
{
debug.str("");
debug << "Slot: " << put_time(*slot_it);
NebulaLog::log("SHOWBACK", Log::DEBUG, debug);
}
//================================================================*/
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Process the history records // Process the history records
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@ -580,12 +659,11 @@ void VirtualMachinePool::calculate_showback(time_t start_time, time_t end_time)
// TODO debug // TODO debug
/*===================================================================== /*=====================================================================
ostringstream st;
int seq; int seq;
history.xpath(seq, "/HISTORY/SEQ", -1); history.xpath(seq, "/HISTORY/SEQ", -1);
st << "VM " << vid << " SEQ " << seq << endl debug.str("");
debug << "VM " << vid << " SEQ " << seq << endl
<< "h_stime " << h_stime << endl << "h_stime " << h_stime << endl
<< "h_etime " << h_etime << endl << "h_etime " << h_etime << endl
<< "cpu_cost " << cpu_cost << endl << "cpu_cost " << cpu_cost << endl
@ -593,7 +671,7 @@ void VirtualMachinePool::calculate_showback(time_t start_time, time_t end_time)
<< "cpu " << cpu << endl << "cpu " << cpu << endl
<< "mem " << mem; << "mem " << mem;
NebulaLog::log("SHOWBACK", Log::DEBUG, st); NebulaLog::log("SHOWBACK", Log::DEBUG, debug);
//====================================================================*/ //====================================================================*/
for ( slot_it = showback_slots.begin(); slot_it != showback_slots.end()-1; slot_it++ ) for ( slot_it = showback_slots.begin(); slot_it != showback_slots.end()-1; slot_it++ )
@ -614,9 +692,9 @@ void VirtualMachinePool::calculate_showback(time_t start_time, time_t end_time)
etime = (t_next < h_etime) ? t_next : h_etime; //min(t_next, h_etime); etime = (t_next < h_etime) ? t_next : h_etime; //min(t_next, h_etime);
} }
int n_hours = difftime(etime, stime) / 60 / 60; float n_hours = difftime(etime, stime) / 60 / 60;
int cost = 0; float cost = 0;
cost += cpu_cost * cpu * n_hours; cost += cpu_cost * cpu * n_hours;
cost += mem_cost * mem * n_hours; cost += mem_cost * mem * n_hours;
@ -668,11 +746,12 @@ void VirtualMachinePool::calculate_showback(time_t start_time, time_t end_time)
vm->unlock(); vm->unlock();
} }
tm tmp_tm = *localtime(&vm_month_it->first); tmp_tm = *localtime(&vm_month_it->first);
body.str(""); body.str("");
// TODO: truncate float values to 2 decimals? string cost = one_util::float_to_str(vm_month_it->second.first);
string hours = one_util::float_to_str(vm_month_it->second.second);
body << "<SHOWBACK>" body << "<SHOWBACK>"
<< "<VMID>" << vmid << "</VMID>" << "<VMID>" << vmid << "</VMID>"
@ -683,8 +762,8 @@ void VirtualMachinePool::calculate_showback(time_t start_time, time_t end_time)
<< "<GNAME>" << gname << "</GNAME>" << "<GNAME>" << gname << "</GNAME>"
<< "<YEAR>" << tmp_tm.tm_year + 1900 << "</YEAR>" << "<YEAR>" << tmp_tm.tm_year + 1900 << "</YEAR>"
<< "<MONTH>" << tmp_tm.tm_mon + 1 << "</MONTH>" << "<MONTH>" << tmp_tm.tm_mon + 1 << "</MONTH>"
<< "<COST>" << vm_month_it->second.first << "</COST>" << "<COST>" << cost << "</COST>"
<< "<HOURS>" << vm_month_it->second.second << "</HOURS>" << "<HOURS>" << hours << "</HOURS>"
<< "</SHOWBACK>"; << "</SHOWBACK>";
oss.str(""); oss.str("");
@ -709,16 +788,16 @@ void VirtualMachinePool::calculate_showback(time_t start_time, time_t end_time)
// TODO: debug // TODO: debug
/*================================================================= //*=================================================================
ostringstream st; debug.str("");
st << "VM " << vm_it->first debug << "VM " << vm_it->first
<< " cost for Y " << tmp_tm.tm_year + 1900 << " cost for Y " << tmp_tm.tm_year + 1900
<< " M " << tmp_tm.tm_mon + 1 << " M " << tmp_tm.tm_mon + 1
<< " COST " << vm_month_it->second.first << "" << " COST " << cost << ""
<< " HOURS " << vm_month_it->second.second; << " HOURS " << hours;
NebulaLog::log("SHOWBACK", Log::DEBUG, st); NebulaLog::log("SHOWBACK", Log::DEBUG, debug);
//================================================================*/ //================================================================*/
} }
} }