/usr/lib/one/ruby/acct/oneacct.rb is in opennebula 3.4.1-4.1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | # --------------------------------------------------------------------------
# Copyright 2002-2012, C12G Labs S.L.
#
# This file is part of OpenNebula addons.
#
# OpenNebula addons are free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either version 3 of
# the License, or the hope That it will be useful, but (at your
# option) any later version.
#
# OpenNebula addons are distributed in WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License
# along with OpenNebula addons. If not, see
# <http://www.gnu.org/licenses/>
# --------------------------------------------------------------------------
require 'acct/watch_helper'
class AcctClient
def initialize(filters={})
@filters=filters
@deltas=[]
@users={}
end
def account(time_start=nil, time_end=nil, user_id=nil)
@filters[:start]=time_start if time_start
@filters[:end]=time_end if time_end
@filters[:user]=user_id if user_id
get_users_consumption
@users
end
private
def get_users_consumption
# Get all the deltas that match the filters
@deltas=calculate_deltas.map {|q| q.values }
@users=slices_by_user
user_slices_and_deltas_to_vms
end
def slices_by_user
# Get all VM slices that match the filters
query=get_vm_slices(@filters)
# This hash will hold the users with the resources consumed
users={}
query.each do |reg|
vm=reg.vm
uid=vm.uid.to_i
# Create a new user register if it still does not exist
user=users[uid]||={
:vm_slices => [],
}
user[:vm_slices] << reg.values
end
users
end
def user_slices_and_deltas_to_vms
@users.each do |user, data|
# Get the VM ids array for this user
vms=data[:vm_slices].map {|vm| vm[:id] }.sort.uniq
data[:vms]={}
vms.each do |vm|
# Get the slices array for this VM
slices=data[:vm_slices].select {|slice| slice[:id]==vm }
data[:vms][vm]={
:slices => [],
:time => 0,
}
# Get the deltas sum for this VM
vm_delta=@deltas.find {|d| d[:vm_id]==vm }
data[:vms][vm][:network]=vm_delta
data[:vms][vm][:vmid]=vm
# Calculate the time consumed by the VM
slices.each do |slice|
data[:vms][vm][:slices] << slice
time=calculate_time(slice,
@filters[:start], @filters[:end])
data[:vms][vm][:time]+=time
end
end
# Delete redundant slices data
data.delete(:vm_slices)
end
end
def get_vm_slices(filters={})
vms=WatchHelper::Register
query=vms.join(:vms, :id => :vm_id)
query=query.filter({:vms__uid => filters[:user]}) if filters[:user]
query=query.filter(
{:retime => 0} | (:retime > filters[:start])) if filters[:start]
query=query.filter(:rstime <= filters[:end]) if filters[:end]
query
end
def get_deltas(filters={})
if filters[:data]
query=filters[:data]
else
query=WatchHelper::VmDelta
end
query=query.filter( :ptimestamp >= filters[:start] ) if filters[:start]
query=query.filter( :ptimestamp <= filters[:end] ) if filters[:end]
query=query.filter( { :vm_id => filters[:vmid] } ) if filters[:vmid]
query
end
def calculate_deltas
query=WatchHelper::VmDelta.select(
:ptimestamp, :vm_id,
'sum(net_tx) AS net_tx'.lit, 'sum(net_rx) AS net_rx'.lit)
query=query.group(:vm_id)
new_filters=@filters.merge(:data => query)
get_deltas(new_filters)
end
def calculate_time(slice, period_start, period_end)
ts=slice[:rstime].to_i
te=slice[:retime].to_i
pstart=period_start.to_i
pend=period_end.to_i
pend=Time.now.to_i if pend==0
ts=pstart if ts<pstart
if te>pend or te==0
te=pend
end
te-ts
end
end
if $0 == __FILE__
require 'json'
acct=AcctClient.new(
:start => 1319476322,
:end => 1319637455
)
a=acct.account()
puts JSON.pretty_generate(a)
end
|