1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-20 10:50:08 +03:00

Merge remote-tracking branch 'origin/feature-720'

This commit is contained in:
Ruben S. Montero 2011-08-30 16:49:58 +02:00
commit 2d59f11854
7 changed files with 665 additions and 154 deletions

View File

@ -0,0 +1,446 @@
require 'helper/test_helper.rb'
describe "VmWatchClient tests" do
before(:all) do
clean_db
@mock_client = MockClient.new
@monitoring = OneWatch::VmMonitoring.new
@watch_client = OneWatchClient::VmWatchClient.new
@db = WatchHelper::DB
@db[:vms].count.should eql(0)
end
it "1 VM, 1 timestamp. Check totals, sums and resource info" do
@monitoring.set_mock_timestamp(100)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(0)
values = {
:cpu => 1,
:memory => 128,
:net_tx => 200,
:net_rx => 400,
:last_poll => 90,
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 0,
:rstime => 0,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(1, values)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(1)
end
it "should check all the monitoring resources are shown by default" do
mon = @watch_client.resource_monitoring(1)
mon[:id].should eql(1)
mon[:resource].should eql("VM")
monitoring = mon[:monitoring]
monitoring.keys.size.should eql(4)
monitoring[:cpu_usage].size.should eql(1)
monitoring[:cpu_usage].first.should eql([90,1])
monitoring[:mem_usage].size.should eql(1)
monitoring[:mem_usage].first.should eql([90,128])
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([90,200])
monitoring[:net_rx].size.should eql(1)
monitoring[:net_rx].first.should eql([90,400])
end
it "should check all the monitoring resources are shown by default and filtered" do
mon = @watch_client.resource_monitoring(1, nil, :uid=>2)
mon[:id].should eql(1)
mon[:resource].should eql("VM")
monitoring = mon[:monitoring]
monitoring.keys.size.should eql(4)
monitoring[:cpu_usage].size.should eql(1)
monitoring[:cpu_usage].first.should eql([90,1])
monitoring[:mem_usage].size.should eql(1)
monitoring[:mem_usage].first.should eql([90,128])
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([90,200])
monitoring[:net_rx].size.should eql(1)
monitoring[:net_rx].first.should eql([90,400])
end
it "should check no info for non exisiting user" do
mon = @watch_client.resource_monitoring(1, nil, :uid=>1)
mon.should eql(nil)
end
it "should check only one monitoring resource is shown if specified" do
mon = @watch_client.resource_monitoring(1, [:net_tx])
monitoring = mon[:monitoring]
monitoring.keys.size.should eql(1)
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([90,200])
end
it "should check only two monitoring resources are shown if specified" do
mon = @watch_client.resource_monitoring(1, [:net_tx, :cpu_usage])
monitoring = mon[:monitoring]
monitoring.keys.size.should eql(2)
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([90,200])
monitoring[:cpu_usage].size.should eql(1)
monitoring[:cpu_usage].first.should eql([90,1])
end
it "should check all the total monitoring resources are shown by default" do
mon = @watch_client.total_monitoring
mon[:resource].should eql("VM_POOL")
monitoring = mon[:monitoring]
monitoring[:total].size.should eql(1)
monitoring[:total].first.should eql([100,1])
monitoring[:active].size.should eql(1)
monitoring[:active].first.should eql([100,1])
monitoring[:error].size.should eql(0)
monitoring[:cpu_usage].size.should eql(1)
monitoring[:cpu_usage].first.should eql([90,1])
monitoring[:mem_usage].size.should eql(1)
monitoring[:mem_usage].first.should eql([90,128])
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([90,200])
monitoring[:net_rx].size.should eql(1)
monitoring[:net_rx].first.should eql([90,400])
end
it "should check only one total monitoring resources is shown if specified" do
mon = @watch_client.total_monitoring([:total])
mon[:resource].should eql("VM_POOL")
monitoring = mon[:monitoring]
monitoring.keys.size.should eql(1)
monitoring[:total].size.should eql(1)
monitoring[:total].first.should eql([100,1])
end
it "should return an empty Hash if no valid monitoring resource" do
mon = @watch_client.resource_monitoring(1, [:oranges])
mon[:monitoring].empty?.should eql(true)
end
it "should return nil if the VM does not exist" do
mon = @watch_client.resource_monitoring(100, [:oranges])
mon.should eql(nil)
end
it "add a second VM" do
@monitoring.set_mock_timestamp(200)
values = {
:cpu => 1,
:memory => 128,
:net_tx => 200,
:net_rx => 400,
:last_poll => 90,
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 0,
:rstime => 0,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(2, values)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(2)
end
it "should check all the monitoring resources are shown by default" do
mon = @watch_client.resource_monitoring(1)
mon[:id].should eql(1)
mon[:resource].should eql("VM")
monitoring = mon[:monitoring]
monitoring.keys.size.should eql(4)
monitoring[:cpu_usage].size.should eql(2)
monitoring[:cpu_usage].first.should eql([90,1])
monitoring[:mem_usage].size.should eql(2)
monitoring[:mem_usage].first.should eql([90,128])
monitoring[:net_tx].size.should eql(2)
monitoring[:net_tx].first.should eql([90,200])
monitoring[:net_rx].size.should eql(2)
monitoring[:net_rx].first.should eql([90,400])
mon = @watch_client.resource_monitoring(2)
mon[:id].should eql(2)
mon[:resource].should eql("VM")
monitoring = mon[:monitoring]
monitoring.keys.size.should eql(4)
monitoring[:cpu_usage].size.should eql(1)
monitoring[:cpu_usage].first.should eql([90,1])
monitoring[:mem_usage].size.should eql(1)
monitoring[:mem_usage].first.should eql([90,128])
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([90,200])
monitoring[:net_rx].size.should eql(1)
monitoring[:net_rx].first.should eql([90,400])
end
it "should check all the total monitoring resources are shown by default" do
mon = @watch_client.total_monitoring
mon[:resource].should eql("VM_POOL")
monitoring = mon[:monitoring]
monitoring[:total].size.should eql(2)
monitoring[:total].first.should eql([100,1])
monitoring[:total][1].should eql([200,2])
monitoring[:active].size.should eql(2)
monitoring[:active].first.should eql([100,1])
monitoring[:active][1].should eql([200,2])
monitoring[:error].size.should eql(0)
monitoring[:cpu_usage].size.should eql(1)
monitoring[:cpu_usage].first.should eql([90,1*2])
monitoring[:mem_usage].size.should eql(1)
monitoring[:mem_usage].first.should eql([90,128*2])
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([90,200*2])
monitoring[:net_rx].size.should eql(1)
monitoring[:net_rx].first.should eql([90,400*2])
end
it "add a third VM" do
@monitoring.set_mock_timestamp(300)
values = {
:cpu => 1,
:memory => 128,
:net_tx => 200,
:net_rx => 400,
:last_poll => 90,
:uid => 3,
:gid => 5,
:history => [
:hid => 7,
:pstime => 150,
:petime => 0,
:rstime => 0,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(3, values)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(3)
end
it "should check the total monitoring resources are filtered by user" do
mon = @watch_client.total_monitoring(nil, :uid=>3)
mon[:resource].should eql("VM_POOL")
monitoring = mon[:monitoring]
monitoring[:total].size.should eql(1)
monitoring[:total].first.should eql([300,1])
monitoring[:active].size.should eql(1)
monitoring[:active].first.should eql([300,1])
monitoring[:error].size.should eql(0)
monitoring[:cpu_usage].size.should eql(1)
monitoring[:cpu_usage].first.should eql([90,1])
monitoring[:mem_usage].size.should eql(1)
monitoring[:mem_usage].first.should eql([90,128])
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([90,200])
monitoring[:net_rx].size.should eql(1)
monitoring[:net_rx].first.should eql([90,400])
end
it "should check the total monitoring resources are filtered by group" do
mon = @watch_client.total_monitoring(nil, :gid=>5)
mon[:resource].should eql("VM_POOL")
monitoring = mon[:monitoring]
monitoring[:total].size.should eql(1)
monitoring[:total].first.should eql([300,1])
monitoring[:active].size.should eql(1)
monitoring[:active].first.should eql([300,1])
monitoring[:error].size.should eql(0)
monitoring[:cpu_usage].size.should eql(1)
monitoring[:cpu_usage].first.should eql([90,1])
monitoring[:mem_usage].size.should eql(1)
monitoring[:mem_usage].first.should eql([90,128])
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([90,200])
monitoring[:net_rx].size.should eql(1)
monitoring[:net_rx].first.should eql([90,400])
end
it "should check the total monitoring resources are filtered by user" do
mon = @watch_client.total_monitoring(nil, :uid=>2)
mon[:resource].should eql("VM_POOL")
monitoring = mon[:monitoring]
monitoring[:total].size.should eql(3)
monitoring[:total].first.should eql([100,1])
monitoring[:total][1].should eql([200,2])
monitoring[:active].last.should eql([300,2])
monitoring[:active].size.should eql(3)
monitoring[:active].first.should eql([100,1])
monitoring[:active][1].should eql([200,2])
monitoring[:active].last.should eql([300,2])
monitoring[:error].size.should eql(0)
monitoring[:cpu_usage].size.should eql(1)
monitoring[:cpu_usage].first.should eql([90,1*2])
monitoring[:mem_usage].size.should eql(1)
monitoring[:mem_usage].first.should eql([90,128*2])
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([90,200*2])
monitoring[:net_rx].size.should eql(1)
monitoring[:net_rx].first.should eql([90,400*2])
end
it "should check the total monitoring resources are filtered by group" do
mon = @watch_client.total_monitoring(nil, :gid=>4)
mon[:resource].should eql("VM_POOL")
monitoring = mon[:monitoring]
monitoring[:total].size.should eql(3)
monitoring[:total].first.should eql([100,1])
monitoring[:total][1].should eql([200,2])
monitoring[:active].last.should eql([300,2])
monitoring[:active].size.should eql(3)
monitoring[:active].first.should eql([100,1])
monitoring[:active][1].should eql([200,2])
monitoring[:active].last.should eql([300,2])
monitoring[:error].size.should eql(0)
monitoring[:cpu_usage].size.should eql(1)
monitoring[:cpu_usage].first.should eql([90,1*2])
monitoring[:mem_usage].size.should eql(1)
monitoring[:mem_usage].first.should eql([90,128*2])
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([90,200*2])
monitoring[:net_rx].size.should eql(1)
monitoring[:net_rx].first.should eql([90,400*2])
end
it "should check no total info for non existing user" do
mon = @watch_client.total_monitoring(nil, :uid=>5)
mon[:resource].should eql("VM_POOL")
monitoring = mon[:monitoring]
monitoring[:total].size.should eql(0)
monitoring[:active].size.should eql(0)
monitoring[:error].size.should eql(0)
monitoring[:cpu_usage].size.should eql(0)
monitoring[:mem_usage].size.should eql(0)
monitoring[:net_tx].size.should eql(0)
monitoring[:net_rx].size.should eql(0)
end
end

View File

@ -18,119 +18,30 @@ module OneWatchClient
require 'acct/watch_helper'
class WatchClient
def vm_monitoring(id, opts=[])
if resource = WatchHelper::Vm[id]
resource_monitoring(
resource,
"VM",
WatchHelper::VM_SAMPLE,
opts
)
TOTAL_COUNT = [:total, :active, :error]
def resource_monitoring(id, monitoring_resources=[], filter={})
# Retrieve Sequel resource
rsql = filter_resource(id, filter)
return nil if rsql.nil?
# By default show all the available monitoring resources.
# If a set of monitoring resources is specified
# select only the allowed ones
allowed_keys = allowed_samples.keys
if monitoring_resources && !monitoring_resources.empty?
monitoring_resources = allowed_keys & monitoring_resources
else
return nil
end
end
def host_monitoring(id, opts=[])
if resource = WatchHelper::Host[id]
resource_monitoring(
resource,
"HOST",
WatchHelper::HOST_SAMPLE,
opts
)
else
return nil
end
end
def vm_total(opts=[])
total_monitoring(
WatchHelper::VmSample,
"VM",
WatchHelper::VM_SAMPLE,
opts
)
end
def host_total(opts=[])
total_monitoring(
WatchHelper::HostSample,
"HOST",
WatchHelper::HOST_SAMPLE,
opts
)
end
private
def total_monitoring(rsql, kind, allowed_samples, monitoring_resources)
hash = Hash.new
hash[:resource] = "#{kind.upcase}_POOL"
mon = Hash.new
monitoring_resources.each { |opt|
opt = opt.to_sym
if allowed_samples.has_key?(opt)
mon[opt] = sum_monitoring(rsql, kind, opt)
elsif [:total, :active, :error].include?(opt)
mon[opt] = count_monitoring(rsql, opt)
end
}
hash[:monitoring] = mon
hash
end
def sum_monitoring(rsql, kind, mr)
a = Array.new
WatchHelper::DB.fetch(
"SELECT last_poll,sum(u#{mr}) AS sum_#{mr} FROM " <<
"(SELECT last_poll, max(#{mr}) AS u#{mr} " <<
"FROM #{kind.downcase}_samples " <<
"GROUP BY #{kind.downcase}_id, last_poll) " <<
"GROUP BY last_poll;"
) do |row|
if row[:last_poll] && row[:last_poll] != 0
a << [row[:last_poll], row["sum_#{mr}".to_sym].to_i]
end
monitoring_resources = allowed_keys
end
a
end
def count_monitoring(rsql, opt)
resources = case opt
when :total then rsql
when :active then rsql.active
when :error then rsql.error
else return nil
end
a = Array.new
resources.group_and_count(:timestamp).all.each { |row|
a << [row[:timestamp], row[:count].to_i]
}
a
end
def resource_monitoring(rsql, kind, allowed_sample, monitoring_resources)
hash = Hash.new
hash[:resource] = kind
hash[:id] = rsql.id
# Initialize monitoring information
mon = Hash.new
monitoring_resources.each { |mr|
if allowed_sample.has_key?(mr.to_sym)
mon[mr] = Array.new
else
monitoring_resources.delete(mr)
end
mon[mr] = Array.new
}
# Retrieve information
rsql.samples_dataset.map { |sample|
monitoring_resources.each { |mr|
if sample.last_poll && sample.last_poll != 0
@ -139,9 +50,183 @@ module OneWatchClient
}
}
# Format response in a Hash
hash = Hash.new
hash[:resource] = kind
hash[:id] = rsql.id
hash[:monitoring] = mon
hash
end
def total_monitoring(monitoring_resources=[], filter={})
# Retrieve Sequel resource
rsql = filter_pool(filter)
return nil if rsql.nil?
# By default show all the available monitoring resources.
# If a set of monitoring resources is specified
# select only the allowed ones
allowed_keys = allowed_samples.keys + TOTAL_COUNT
if monitoring_resources && !monitoring_resources.empty?
monitoring_resources = allowed_keys & monitoring_resources
else
monitoring_resources = allowed_keys
end
# Retrieve information
mon = Hash.new
monitoring_resources.each { |opt|
opt = opt.to_sym
if allowed_samples.has_key?(opt)
mon[opt] = sum_monitoring(rsql, opt)
elsif TOTAL_COUNT.include?(opt)
mon[opt] = count_monitoring(rsql, opt)
end
}
# Format response in a Hash
hash = Hash.new
hash[:resource] = "#{kind.upcase}_POOL"
hash[:monitoring] = mon
hash
end
private
def sum_monitoring(rsql, mr)
# Get the MAX for each VM and last_poll value
max_per_vm =
rsql.
group(:id, :last_poll).
select(:last_poll, :MAX[mr.to_sym].as(:max_mr))
# SUM the monitoring resource for each last_poll value
last_poll_and_sum =
max_per_vm.
from_self.
group(:last_poll).
select(:last_poll, :SUM[:max_mr].as(:sum_mr))
# Retrieve the information in an Array
a = Array.new
last_poll_and_sum.each do |row|
if row[:last_poll] && row[:last_poll] != 0
a << [row[:last_poll], row[:sum_mr].to_i]
end
end
a
end
def count_monitoring(rsql, opt)
resources = case opt
when :total then rsql
when :active then active(rsql)
when :error then error(rsql)
else return nil
end
a = Array.new
resources.group_and_count(:timestamp).all.each { |row|
a << [row[:timestamp], row[:count].to_i]
}
a
end
end
class HostWatchClient < WatchClient
def pool
WatchHelper::Host
end
def allowed_samples
WatchHelper::HOST_SAMPLE
end
def kind
"HOST"
end
def active(pool)
pool.filter('state < 3')
end
def error(pool)
pool.filter(:state=>3)
end
def filter_pool(filter)
if filter[:uid]
filter[:uid]==0 ? (hosts = pool) : (return nil)
elsif filter[:gid]
filter[:uid]==0 ? (hosts = pool) : (return nil)
else
hosts = pool
end
hosts.join(WatchHelper::HostSample, :host_id=>:id)
end
def filter_resource(id, filter)
rsql = pool[id]
return nil if rsql.nil?
if filter[:uid]
filter[:uid]==0 ? rsql : nil
elsif filter[:gid]
filter[:gid]==0 ? rsql : nil
else
rsql
end
end
end
class VmWatchClient < WatchClient
def pool
WatchHelper::Vm
end
def allowed_samples
WatchHelper::VM_SAMPLE
end
def kind
"VM"
end
def active(pool)
pool.filter(:state=>3)
end
def error(pool)
pool.filter(:state=>7)
end
def filter_pool(filter)
if filter[:uid]
vms = pool.filter(:uid=>filter[:uid])
elsif filter[:gid]
vms = pool.filter(:gid=>filter[:gid])
else
vms = pool
end
vms.join(WatchHelper::VmSample, :vm_id=>:id)
end
def filter_resource(id, filter)
rsql = pool[id]
return nil if rsql.nil?
if filter[:uid]
filter[:uid]==rsql.uid ? rsql : nil
elsif filter[:gid]
filter[:gid]==rsql.gid ? rsql : nil
else
rsql
end
end
end
end

View File

@ -51,11 +51,11 @@ module WatchHelper
}
VM_SAMPLE = {
:cpu => {
:cpu_usage => {
:type => Integer,
:path => 'CPU'
},
:memory => {
:mem_usage => {
:type => Integer,
:path => 'MEMORY'
},
@ -216,28 +216,12 @@ module WatchHelper
unrestrict_primary_key
many_to_one :vm
def self.active
self.filter(:state=>3)
end
def self.error
self.filter(:state=>7)
end
end
class HostSample < Sequel::Model
unrestrict_primary_key
many_to_one :host
def self.active
self.filter('state < 3')
end
def self.error
self.filter(:state=>3)
end
end
class Register < Sequel::Model
@ -290,9 +274,9 @@ module WatchHelper
v.name = vm['NAME']
v.uid = vm['UID'].to_i
v.gid = vm['GID'].to_i
v.mem = vm['MEMORY'].to_i
v.cpu = vm['CPU'].to_i
v.vcpu = vm['VCPU'].to_i
v.mem = vm['TEMPLATE/MEMORY'].to_i
v.cpu = vm['TEMPLATE/CPU'].to_i
v.vcpu = vm['TEMPLATE/VCPU'].to_i
v.stime = vm['STIME'].to_i
v.etime = vm['ETIME'].to_i
}

View File

@ -294,28 +294,26 @@ class SunstoneServer
#
############################################################################
def get_monitoring(id, resource, monitor_resources)
watch_client = OneWatchClient::WatchClient.new
columns = monitor_resources.split(',')
rc = case resource
def get_monitoring(id, resource, monitor_resources, gid)
watch_client = case resource
when "vm","VM"
if id
watch_client.vm_monitoring(id, columns)
else
watch_client.vm_total(columns)
end
OneWatchClient::VmWatchClient.new
when "host","HOST"
if id
watch_client.host_monitoring(id, columns)
else
watch_client.host_total(columns)
end
OneWatchClient::HostWatchClient.new
else
error = Error.new("Monitoring not supported for this resource: #{resource}")
error = Error.new("Monitoring not supported for this resource: #{resource}")
return [200, error.to_json]
end
columns = monitor_resources.split(',')
columns.map!{|e| e.to_sym}
if id
rc = watch_client.resource_monitoring(id.to_i, columns)
else
rc = watch_client.total_monitoring(columns)
end
if rc.nil?
error = Error.new("There is no monitoring information for #{resource} #{id}")
return [500, error.to_json]

View File

@ -26,13 +26,13 @@ var graph1 = {
var graph2 = {
title : "graph2",
monitor_resources : "cpu",
monitor_resources : "cpu_usage",
history_length : HISTORY_LENGTH
};
var graph3 = {
title : "graph3",
monitor_resources : "memory",
monitor_resources : "mem_usage",
history_length : HISTORY_LENGTH
};

View File

@ -26,12 +26,12 @@ loadVNC();
var vm_graphs = [
{ title : "CPU",
monitor_resources : "cpu",
monitor_resources : "cpu_usage",
humanize_figures : false,
history_length : VM_HISTORY_LENGTH
},
{ title : "Memory",
monitor_resources : "memory",
monitor_resources : "mem_usage",
humanize_figures : true,
history_length : VM_HISTORY_LENGTH
},

View File

@ -33,14 +33,10 @@ else
PLUGIN_CONFIGURATION_FILE = ONE_LOCATION+"/etc/sunstone-plugins.yaml"
end
HOST_LOG_FOLDER = LOG_LOCATION+"/OneMonitor/host"
VM_LOG_FOLDER = LOG_LOCATION+"/OneMonitor/vm"
SUNSTONE_ROOT_DIR = File.dirname(__FILE__)
$: << RUBY_LIB_LOCATION
$: << SUNSTONE_ROOT_DIR+'/models'
$: << SUNSTONE_ROOT_DIR+'/share/OneMonitor'
##############################################################################
# Required libraries
@ -183,14 +179,16 @@ get '/:resource/monitor' do
@SunstoneServer.get_monitoring(
nil,
params[:resource],
params[:monitor_resources])
params[:monitor_resources],
session[:user_gid])
end
get '/:resource/:id/monitor' do
@SunstoneServer.get_monitoring(
params[:id],
params[:resource],
params[:monitor_resources])
params[:monitor_resources],
session[:user_gid])
end