[Ovirt-devel] [PATCH] integrated backend monitoring api to drive graphs on hardware pool views
Mohammed Morsi
mmorsi at redhat.com
Wed Jun 4 23:23:31 UTC 2008
Signed-off-by: Mohammed Morsi <mmorsi at redhat.com>
---
wui/src/app/controllers/graph_controller.rb | 270 +-
wui/src/app/util/stats/DummyData.rb |12641 -------------------------
wui/src/app/util/stats/Stats.rb | 68 +-
wui/src/app/util/stats/StatsRequest.rb | 2 +
wui/src/app/util/stats/StatsTypes.rb | 333 +
wui/src/app/util/stats/statsTest.rb | 49 +-
wui/src/app/views/graph/history_graphs.rhtml | 4 +-
wui/src/app/views/graph/snapshot_graph.rhtml | 36 +-
wui/src/app/views/host/_grid.rhtml | 5 +-
wui/src/app/views/storage/_grid.rhtml | 6 +-
wui/src/app/views/storage/addstorage.html.erb | 2 +-
wui/src/app/views/vm/_grid.rhtml | 2 +-
wui/src/public/stylesheets/components.css | 4 +-
13 files changed, 564 insertions(+), 12858 deletions(-)
delete mode 100644 wui/src/app/util/stats/DummyData.rb
create mode 100644 wui/src/app/util/stats/StatsTypes.rb
diff --git a/wui/src/app/controllers/graph_controller.rb b/wui/src/app/controllers/graph_controller.rb
index 80ece7e..0a7c4da 100644
--- a/wui/src/app/controllers/graph_controller.rb
+++ b/wui/src/app/controllers/graph_controller.rb
@@ -1,4 +1,4 @@
-# require 'util/stats/Stats'
+require 'util/stats/Stats'
class GraphController < ApplicationController
layout nil
@@ -94,44 +94,67 @@ class GraphController < ApplicationController
# generate layout for history graphs
def history_graphs
@id = params[:id]
- @peak_history = { :color => 'red', :values => [ 100, 99, 98, 93, 95, 12, 92] }
- @avg_history = { :color => 'blue', :values => [12, 23, 42, 33, 12, 23, 65] }
+ @peak_history = { :color => 'red', :values => [0,0,0,0,0,0,0], :dataPoints => [0,0,0,0,0,0,0] }
+ @avg_history = { :color => 'blue', :values => [0,0,0,0,0,0,0], :dataPoints => [0,0,0,0,0,0,0] }
end
# retrieves data for history graphs
def history_graph_data
history_graphs
target = params[:target]
+ devclass = DEV_KEY_CLASSES[target]
+ avgcounter = DEV_KEY_AVGCOUNTERS[target]
+ peakcounter = nil
@pool = Pool.find(@id)
today = Time.now
- #requestList = [ ]
+ firstday = today - 6
dates = [ Date::ABBR_MONTHNAMES[today.month] + ' ' + today.day.to_s ]
0.upto(6){ |x| # TODO get # of days from wui
dte = today - x
dates.push ( Date::ABBR_MONTHNAMES[dte.month] + ' ' + dte.day.to_s )
- #requestList.push ( StatsRequest.new (@pool.id.to_s, target, 0, "used", dte.to_i - 3600, 3600, 0),
- # StatsRequest.new (@pool.id.to_s, target, 0, "peak", dte.to_i - 3600, 3600, 0) )
+ }
+
+ requestList = [ ]
+ @pool.hosts.each { |host|
+ if target == "cpu"
+ 0.upto(host.num_cpus - 1){ |x|
+ requestList.push ( StatsRequest.new (host.hostname, devclass, x, avgcounter, 0, 0, RRDResolution::Long) ) #, # one weeks worth of data
+ # StatsRequest.new (@pool.id.to_s, devclass, x, peakcounter, firstday.to_i - 3600, 604800, 3600))
+ }
+ else
+ requestList.push ( StatsRequest.new (host.hostname, devclass, 0, avgcounter, 0, 0, RRDResolution::Long) ) #,
+ # StatsRequest.new (@pool.id.to_s, devclass, 0, peakcounter, firstday.to_i - 3600, 604800, 3600))
+ end
}
dates.reverse! # want in ascending order
- #requestList.reverse!
- #statsList = getStatsData?( requestList )
- #statsList.each { |stat|
- # devClass = stat.get_devClass?
- # counter = stat.get_counter?
- # stat.get_data?.each{ |data|
- # value = data.get_value?.to_i
- # if devClass == target
- # if counter == "used"
- # @avg_history[:values].push value
- # else
- # #elsif counter == "peak"
- # @peak_history[:values].push value
- # end
- # end
- # }
- #}
+ statsList = getStatsData?( requestList )
+ statsList.each { |stat|
+ counter = stat.get_counter?
+ stat.get_data?.each{ |data|
+ timestamp = data.get_timestamp?
+ valueindex = ((timestamp.to_i - firstday.to_i) / 86400).to_i # 86400 secs per day
+ value = data.get_value?
+ if !value.nan?
+ if counter == avgcounter
+ @avg_history[:values][valueindex] += value.to_i
+ @avg_history[:dataPoints][valueindex] += 1
+ elsif counter == peakcounter
+ @peak_history[:values][valueindex] += value.to_i
+ @peak_history[:dataPoints][valueindex] += 1
+ end
+ end
+ }
+ }
+
+ # avgerage out history for each day
+ 0.upto(@avg_history[:values].size - 1){ |x|
+ (@avg_history[:values][x] /= @avg_history[:dataPoints][x]) if (@avg_history[:dataPoints][x] != 0)
+ }
+ 0.upto(@peak_history[:values].size - 1){ |x|
+ (@peak_history[:values][x] /= @peak_history[:dataPoints][x]) if (@peak_history[:dataPoints][x] != 0)
+ }
graph_object = {
:timepoints => dates,
@@ -192,58 +215,65 @@ class GraphController < ApplicationController
# generate layout for snapshot graphs
def snapshot_graph
@id = params[:id]
- @target = params[:target]
+ @host = params[:host]
- #ret_time = Time.now.to_i
- #@snapshots = { :avg => { :overall_load => 0, :cpu => 0, :in => 0, :out => 0, :io => 0 },
- # :peak => { :overall_load => 0, :cpu => 0, :in => 0, :out => 0, :io => 0 }}
- #requestList = []
- #requestList << StatsRequest.new(@id.to_s, "system", 0, "used", ret_time, 3600, 0)
- #requestList << StatsRequest.new(@id.to_s, "system", 0, "peak", ret_time, 3600, 0)
- #requestList << StatsRequest.new(@id.to_s, "cpu", 0, "used", ret_time, 3600, 0)
- #requestList << StatsRequest.new(@id.to_s, "cpu", 0, "peak", ret_time, 3600, 0)
- #requestList << StatsRequest.new(@id.to_s, "in", 0, "used", ret_time, 3600, 0)
- #requestList << StatsRequest.new(@id.to_s, "in", 0, "peak", ret_time, 3600, 0)
- #requestList << StatsRequest.new(@id.to_s, "out", 0, "used", ret_time, 3600, 0)
- #requestList << StatsRequest.new(@id.to_s, "out", 0, "peak", ret_time, 3600, 0)
- #requestList << StatsRequest.new(@id.to_s, "io", 0, "used", ret_time, 3600, 0)
- #requestList << StatsRequest.new(@id.to_s, "io", 0, "peak", ret_time, 3600, 0)
- #statsList = getStatsData?( requestList )
- #statsList.each { |stat|
- # devClass = stat.get_devClass?
- # counter = stat.get_counter?
- # stat.get_data?.each{ |data|
- # value = data.get_value?.to_i
- # if counter == "used"
- # if devClass == "system"
- # @snapshots[:avg][:overall_load] = value
- # elsif devClass == "cpu"
- # @snapshots[:avg][:cpu] = value
- # elsif devClass == "in"
- # @snapshots[:avg][:in] = value
- # elsif devClass == "out"
- # @snapshots[:avg][:out] = value
- # elsif devClass == "io"
- # @snapshots[:avg][:io] = value
- # end
- # else
- # #elsif counter == "peak"
- # if devClass == "system"
- # @snapshots[:peak][:overall_load] = value.to_i
- # elsif devClass == "cpu"
- # @snapshots[:peak][:cpu] = value.to_i
- # elsif devClass == "in"
- # @snapshots[:peak][:in] = value.to_i
- # elsif devClass == "out"
- # @snapshots[:peak][:out] = value.to_i
- # elsif devClass == "io"
- # @snapshots[:peak][:io] = value.to_i
- # end
- # end
- # }
- #}
- @snapshots = { :avg => { :overall_load => 500, :cpu => 10, :in => 100, :out => 1024, :io => 200 },
- :peak => { :overall_load => 100, :cpu => 50, :in => 12, :out => 72, :io => 100 } }
+ pool = Pool.find(@id)
+
+ @snapshots = { :avg => { 'load' => 0, 'cpu' => 0, 'netin' => 0, 'netout' => 0, 'memory' => 0 },
+ :peak => { 'load' => 0, 'cpu' => 0, 'netin' => 0, 'netout' => 0, 'memory' => 0 }}
+
+ requestList = []
+ if(@host == nil)
+ pool.hosts.each{ |host|
+ requestList += _create_host_snapshot_requests(host.hostname)
+ }
+ else
+ requestList += _create_host_snapshot_requests(@host.hostname)
+ end
+
+ statsList = getStatsData?( requestList )
+ statsList.each { |stat|
+ devClass = stat.get_devClass?
+ counter = stat.get_counter?
+ stat.get_data?.each{ |data|
+ value = data.get_value?
+ if !value.nan?
+ if devClass == DEV_KEY_CLASSES["load"]
+ if counter == DEV_KEY_AVGCOUNTERS["load"]
+ @snapshots[:avg]["load"] = value.to_i
+ elsif counter == DEV_KEY_PEAKCOUNTERS["load"]
+ @snapshots[:peak]["load"] = value.to_i
+ end
+ elsif devClass == DEV_KEY_CLASSES["cpu"]
+ if counter == DEV_KEY_AVGCOUNTERS["cpu"]
+ @snapshots[:avg]["cpu"] = value.to_i
+ elsif counter == DEV_KEY_PEAKCOUNTERS["cpu"]
+ @snapshots[:peak]["cpu"] = value.to_i
+ end
+ elsif devClass == DEV_KEY_CLASSES["netin"]
+ if counter == DEV_KEY_AVGCOUNTERS["netin"]
+ @snapshots[:avg]["netin"] = value.to_i
+ elsif counter == DEV_KEY_PEAKCOUNTERS["netin"]
+ @snapshots[:peak]["netin"] = value.to_i
+ end
+ elsif devClass == DEV_KEY_CLASSES["netout"]
+ if counter == DEV_KEY_AVGCOUNTERS["netout"]
+ @snapshots[:avg]["netout"] = value.to_i
+ elsif counter == DEV_KEY_PEAKCOUNTERS["netout"]
+ @snapshots[:peak]["netout"] = value.to_i
+ end
+ #elsif devClass == DEV_KEY_AVGCOUNTERS["io"]
+ # if counter == DEV_KEY_AVGCOUNTERS["io"]
+ # @snapshots[:peak]["io"] = value.to_i
+ # elsif counter == _dev_key_peak_counters["io"]
+ # @snapshots[:peak]["io"] = value.to_i
+ # end
+ end
+ end
+ }
+ }
+ #@snapshots = { :avg => { :overall_load => 500, :cpu => 10, :in => 100, :out => 1024, :io => 200 },
+ # :peak => { :overall_load => 100, :cpu => 50, :in => 12, :out => 72, :io => 100 } }
end
@@ -252,18 +282,7 @@ class GraphController < ApplicationController
snapshot_graph
target = params[:target]
- snapshot = nil
- if target == 'overall_load'
- snapshot = @snapshots[:avg][:overall_load]
- elsif target == 'cpu'
- snapshot = @snapshots[:avg][:cpu]
- elsif target == 'in'
- snapshot = @snapshots[:avg][:in]
- elsif target == 'out'
- snapshot = @snapshots[:avg][:out]
- elsif target == 'io'
- snapshot = @snapshots[:avg][:io]
- end
+ snapshot = @snapshots[:avg][target]
snapshot_remaining = 1024 - snapshot
@@ -293,57 +312,32 @@ class GraphController < ApplicationController
render :json => graph_object
end
- #This is static test data to show how we would format whatever we get back from the
- #data api. We can pass that api:
- #* node id
- #* type of data we want back (things like summary, memory, storage, etc.)
- #* timeframe we are interested in. This one goes into 'timepoints'
- # and probably would call some rails helpers to format the date info however we want
+ private
+
+ DEV_KEY_CLASSES = { 'cpu' => DevClass::CPU, 'memory' => DevClass::Memory, 'disk' => DevClass::Disk, 'load' => DevClass::Load, 'netin' => DevClass::NIC, 'netout' => DevClass::NIC }
+ DEV_CLASS_KEYS = DEV_KEY_CLASSES.invert
+
+ # TODO this needs fixing / completing (cpu: more than user time? disk: ?, load: correct?, nics: correct?)
+ DEV_KEY_AVGCOUNTERS = { 'cpu' => CpuCounter::User, 'memory' => MemCounter::Used, 'disk' => DiskCounter::Ops_read, 'load' => LoadCounter::Load_1min, 'netin' => NicCounter::Packets_Rx, 'netout' => NicCounter::Packets_Tx }
+ DEV_AVGCOUNTER_KEYS = DEV_KEY_AVGCOUNTERS.invert
+
+ # TODO
+ DEV_KEY_PEAKCOUNTERS = { 'cpu' => nil, 'memory' => nil, 'disk' => nil, 'load' => nil, 'netin' => nil, 'netout' => nil }
+ DEV_PEAKCOUNTER_KEYS = DEV_KEY_PEAKCOUNTERS.invert
+
+ def _create_host_snapshot_requests(hostname)
+ requestList = []
+ requestList << StatsRequest.new(hostname, DEV_KEY_CLASSES['load'], 0, DEV_KEY_AVGCOUNTERS['load'], 0, 0, RRDResolution::Default) # RRDResolution::Long ?
+ #requestList << StatsRequest.new(hostname, "system", 0, "peak", ret_time, 3600, 0)
+ requestList << StatsRequest.new(hostname, DEV_KEY_CLASSES['cpu'], 0, DEV_KEY_AVGCOUNTERS['cpu'], 0, 0, RRDResolution::Default) # TODO instance
+ #requestList << StatsRequest.new(hostname, "cpu", 0, "peak", ret_time, 3600, 0)
+ #requestList << StatsRequest.new(hostname, DEV_KEY_CLASSES['netin'],0, DEV_KEY_AVGCOUNTERS['netin'], 0, 0, RRDResolution::Default)
+ #requestList << StatsRequest.new(hostname, "in", 0, "peak", ret_time, 3600, 0)
+ #requestList << StatsRequest.new(hostname, DEV_KEY_CLASSES['netout'],0, DEV_KEY_AVGCOUNTERS['netout'], 0, 0, RRDResolution::Default)
+ #requestList << StatsRequest.new(hostname, "out", 0, "peak", ret_time, 3600, 0)
+ #requestList << StatsRequest.new(hostname, DEV_KEY_CLASSES["io"],0, DEV_KEY_AVGCOUNTERS["io"], 0, 0, RRDResolution::Default)
+ #requestList << StatsRequest.new(hostname, "io", 0, "peak", ret_time, 3600, 0)
+ return requestList
+ end
- def graph
- if params[:type] =="Memory"
- graph_object = {
- :timepoints => [],
- :dataset => [{
- :name =>'IE',
- :values => [86.64],
- :fill => 'lightblue',
- :stroke => 'blue',
- :strokeWidth => 3
- }
- ]
- }
- elsif params[:type] == "detail"
- graph_object = {
- :timepoints => ["April 1", "April 2","April 3","April 4","April 5","April 6","April 7"],
- :dataset => [{
- :name =>'Peak',
- :values => [75.97, 71.80, 68.16, 56.64,95.97, 81.80, 28.16],
- :fill => 'lightblue',
- :stroke => 'blue',
- :strokeWidth => 3
- }]
- }
- else
- graph_object = {
- :timepoints => ["April 1", "April 2","April 3","April 4"],
- :dataset => [{
- :name =>'Peak',
- :values => [95.97, 91.80, 88.16, 86.64],
- :fill => 'lightblue',
- :stroke => 'blue',
- :strokeWidth => 3
- },
- {
- :name =>'Average',
- :values => [3.39, 2.83, 1.61, 0.00],
- :fill => 'pink',
- :stroke => 'red',
- :strokeWidth => 3
- }
- ]
- }
- end
- render :json => graph_object
- end
end
diff --git a/wui/src/app/util/stats/Stats.rb b/wui/src/app/util/stats/Stats.rb
index 0e9060b..73a6920 100644
--- a/wui/src/app/util/stats/Stats.rb
+++ b/wui/src/app/util/stats/Stats.rb
@@ -21,40 +21,61 @@
$: << '/usr/lib64/ruby/site_ruby/1.8/x86_64-linux'
require 'RRD'
+require 'util/stats/StatsTypes'
require 'util/stats/StatsData'
require 'util/stats/StatsDataList'
require 'util/stats/StatsRequest'
-require 'util/stats/DummyData'
def fetchData?(node, devClass, instance, counter, startTime, duration, interval)
if (interval == 0)
- interval = 10
+ interval = RRDResolution::Default
end
if (startTime == 0)
- start = Time.now.to_i - duration
+ if (duration > 0 )
+ sTime = Time.now.to_i - duration
+ else
+ sTime = Time.now.to_i - 86400
+ end
+ eTime = Time.now.to_i
else
- start = startTime
+ sTime = startTime
+ eTime = sTime + duration
end
- endTime = start + duration
+ # Now mangle based on the intervals
+ start = (sTime / interval).to_i * interval
+ endTime = (eTime / interval).to_i * interval
rrdBase="/var/lib/collectd/rrd/"
- rrdNode=rrdBase + "/" + node + "/"
+ rrdNode=rrdBase + node + "/"
# Now we need to mess a bit to get the right combos
+ case devClass
+ when DevClass::CPU
+ rrdTail = CpuCounter.getRRDPath(instance, counter)
+ lIndex = CpuCounter.getRRDIndex(counter)
+ when DevClass::Memory
+ rrdTail = MemCounter.getRRDPath(instance, counter)
+ lIndex = MemCounter.getRRDIndex(counter)
+ when DevClass::Load
+ rrdTail = LoadCounter.getRRDPath(instance, counter)
+ lIndex = LoadCounter.getRRDIndex(counter)
+ when DevClass::NIC
+ rrdTail = NicCounter.getRRDPath(instance, counter)
+ lIndex = NicCounter.getRRDIndex(counter)
+ when DevClass::Disk
+ rrdTail = DiskCounter.getRRDPath(instance, counter)
+ lIndex = DiskCounter.getRRDIndex(counter)
+ else
+ puts "Nothing for devClass"
+ end
- if ( devClass <=> "cpu" ) == 0
- rrdDev = rrdNode + "cpu-" + instance.to_s
- else
- rrdDev = rrdNode + devClass
- end
-
- rrd = rrdDev + "/" + devClass + "-" + counter + ".rrd"
+ rrd = rrdNode + rrdTail + ".rrd"
returnList = StatsDataList.new(node,devClass,instance, counter)
- (fstart, fend, names, data, interval) = RRD.fetch(rrd, "--start", start, "--end", endTime, "AVERAGE", "-r", interval)
+ (fstart, fend, names, data, interval) = RRD.fetch(rrd, "--start", start.to_s, "--end", endTime.to_s, "AVERAGE", "-r", interval.to_s)
i = 0
# For some reason, we get an extra datapoint at the end. Just chop it off now...
data.delete_at(-1)
@@ -62,33 +83,24 @@ def fetchData?(node, devClass, instance, counter, startTime, duration, interval)
# Now, lets walk the returned data and create the ojects, and put them in a list.
data.each do |vdata|
i += 1
- returnList.append_data( StatsData.new(fstart + interval * i, vdata[0] ))
+ returnList.append_data( StatsData.new(fstart + interval * i, vdata[lIndex] ))
end
return returnList
end
-# This is the Ruby entry point into the world of statistics retrieval
-# for ovirt.
-
-
-# This call takes a list of StatRequest objects.
-# It returns a list of StatsData objects that contain the data
-# that satisifies the request.
-#
-# ToDo:
-# 1) There is currently no error reporting mechanisms implemented
-#
def getStatsData?(statRequestList)
tmpList = []
+
myList = []
-
statRequestList.each do |request|
node = request.get_node?
counter = request.get_counter?
- tmpList =fetchData?(request.get_node?, request.get_devClass?,request.get_instance?, request.get_counter?,request.get_starttime?, request.get_duration?,request.get_precision?)
+ tmpList =fetchData?(request.get_node?, request.get_devClass?,request.get_instance?, request.get_counter?,request.get_starttime?, request.get_duration?,request.get_precision?)
+
+ # Now copy the array returned into the main array
myList << tmpList
end
diff --git a/wui/src/app/util/stats/StatsRequest.rb b/wui/src/app/util/stats/StatsRequest.rb
index 4a0ab28..24088c7 100644
--- a/wui/src/app/util/stats/StatsRequest.rb
+++ b/wui/src/app/util/stats/StatsRequest.rb
@@ -21,6 +21,8 @@
# This is the base level request mechanism for the ovirt statistical
# interface
+require 'util/stats/StatsTypes'
+
#define class StatsRequest
class StatsRequest
def initialize(node, devClass, instance, counter, starttime, duration, precision)
diff --git a/wui/src/app/util/stats/StatsTypes.rb b/wui/src/app/util/stats/StatsTypes.rb
new file mode 100644
index 0000000..6049a2e
--- /dev/null
+++ b/wui/src/app/util/stats/StatsTypes.rb
@@ -0,0 +1,333 @@
+#!/usr/bin/ruby
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Mark Wagner <mwagner at redhat.com>
+#
+# This program is 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; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+$: << '/usr/lib64/ruby/site_ruby/1.8/x86_64-linux'
+
+
+class DevClass
+ def DevClass.add_item(key,value)
+ @hash ||= {}
+ @hash[key]=value
+ end
+
+ def DevClass.const_missing(key)
+ @hash[key]
+ end
+
+ def DevClass.each
+ @hash.each {|key,value| yield(key,value)}
+ end
+
+ def DevClass.getRRDDevName?(key)
+ return @hash.values_at(key)
+ end
+
+
+ DevClass.add_item :CPU, 1
+ DevClass.add_item :Memory, 2
+ DevClass.add_item :Disk, 3
+ DevClass.add_item :Load, 4
+ DevClass.add_item :NIC, 5
+end
+
+
+class DiskCounter
+ def DiskCounter.add_item(key,value)
+ @hash ||= {}
+ @hash[key]=value
+ end
+
+ def DiskCounter.const_missing(key)
+ @hash[key]
+ end
+
+ def DiskCounter.each
+ @hash.each {|key,value| yield(key,value)}
+ end
+
+ def DiskCounter.getRRDPath(instance, counter)
+ extension = ".rrd"
+ path = "disk-dm-" + instance.to_s + "/"
+ case counter
+ when DiskCounter::Merged_read, DiskCounter::Merged_write
+ path += "disk_merged"
+ when DiskCounter::Octets_read, DiskCounter::Octets_write
+ path += "disk_octets"
+ when DiskCounter::Ops_read, DiskCounter::Ops_write
+ path += "disk_ops"
+ when DiskCounter::Time_read, DiskCounter::Time_write
+ path += "disk_time"
+ else
+ puts "Nothing"
+ end
+
+ return path
+ end
+ def DiskCounter.getRRDIndex(counter)
+ case counter
+ when DiskCounter::Merged_read, DiskCounter::Octets_read, DiskCounter::Ops_read, DiskCounter::Time_read
+ localIndex = 0
+ when DiskCounter::Merged_read, DiskCounter::Octets_write, DiskCounter::Ops_write, DiskCounter::Time_write
+ localIndex = 1
+ else
+ localIndex = 0
+ end
+
+ return localIndex
+ end
+
+ DiskCounter.add_item :Merged_read, 1
+ DiskCounter.add_item :Merged_write, 2
+ DiskCounter.add_item :Octets_read, 3
+ DiskCounter.add_item :Octets_write, 4
+ DiskCounter.add_item :Ops_read, 5
+ DiskCounter.add_item :Ops_write, 6
+ DiskCounter.add_item :Time_read, 7
+ DiskCounter.add_item :Time_write, 8
+end
+
+class CpuCounter
+ def CpuCounter.add_item(key,value)
+ @hash ||= {}
+ @hash[key]=value
+ end
+
+ def CpuCounter.const_missing(key)
+ @hash[key]
+ end
+
+ def CpuCounter.each
+ @hash.each {|key,value| yield(key,value)}
+ end
+
+ def CpuCounter.getRRDPath(instance, counter)
+ extension = ".rrd"
+ path = "cpu-" + instance.to_s + "/cpu-"
+ case counter
+ when CpuCounter::Idle
+ path += "idle"
+ when CpuCounter::Interrupt
+ path += "interrupt"
+ when CpuCounter::Nice
+ path += "nice"
+ when CpuCounter::Softirq
+ path += "softirq"
+ when CpuCounter::Steal
+ path += "steal"
+ when CpuCounter::System
+ path += "system"
+ when CpuCounter::User
+ path += "user"
+ when CpuCounter::Wait
+ path += "wait"
+ else
+ puts "Nothing"
+ end
+
+ return path
+ end
+
+
+ def CpuCounter.getRRDIndex(counter)
+ return 0
+ end
+
+
+ CpuCounter.add_item :Idle, 1
+ CpuCounter.add_item :Interrupt, 2
+ CpuCounter.add_item :Nice, 3
+ CpuCounter.add_item :Softirq, 4
+ CpuCounter.add_item :Steal, 5
+ CpuCounter.add_item :System, 6
+ CpuCounter.add_item :User, 7
+ CpuCounter.add_item :Wait, 8
+end
+
+class MemCounter
+ def MemCounter.add_item(key,value)
+ @hash ||= {}
+ @hash[key]=value
+ end
+
+ def MemCounter.const_missing(key)
+ @hash[key]
+ end
+
+ def MemCounter.each
+ @hash.each {|key,value| yield(key,value)}
+ end
+
+ def MemCounter.getRRDPath(instance, counter)
+ path = "memory/memory-"
+ case counter
+ when MemCounter::Buffered
+ path += "buffered"
+ when CpuCounter::Cached
+ path += "cache"
+ when MemCounter::Free
+ path += "free"
+ when MemCounter::Used
+ path += "used"
+ else
+ puts "Nothing"
+ end
+ return path
+ end
+
+ def MemCounter.getRRDIndex(counter)
+ return 0
+ end
+
+
+ MemCounter.add_item :Buffered, 1
+ MemCounter.add_item :Cached, 2
+ MemCounter.add_item :Free, 3
+ MemCounter.add_item :Used, 4
+end
+
+class NicCounter
+ def NicCounter.add_item(key,value)
+ @hash ||= {}
+ @hash[key]=value
+ end
+
+ def NicCounter.const_missing(key)
+ @hash[key]
+ end
+
+ def NicCounter.each
+ @hash.each {|key,value| yield(key,value)}
+ end
+
+ def NicCounter.getRRDPath(instance, counter)
+ extension = ".rrd"
+ path = "interface/"
+ case counter
+ when NicCounter::Errors_rx, NicCounter::Errors_tx
+ path += "if_errors-eth" + instance.to_s
+ when NicCounter::Octets_rx, NicCounter::Octets_tx
+ path += "if_octets-eth" + instance.to_s
+ when NicCounter::Packets_rx, NicCounter::Packets_tx
+ path += "if_packets-eth" + instance.to_s
+ else
+ puts "Nothing"
+ end
+
+ return path
+ end
+
+ def NicCounter.getRRDIndex(counter)
+ case counter
+ when NicCounter::Errors_rx
+ localIndex = 0
+ when NicCounter::Errors_tx
+ localIndex = 1
+ when NicCounter::Octets_rx
+ localIndex = 0
+ when NicCounter::Octets_tx
+ localIndex = 1
+ when NicCounter::Packets_rx
+ localIndex = 0
+ when NicCounter::Packets_tx
+ localIndex = 1
+ else
+ localIndex = 0
+ end
+
+ return localIndex
+ end
+
+
+ NicCounter.add_item :Errors_rx, 1
+ NicCounter.add_item :Errors_tx, 2
+ NicCounter.add_item :Octets_rx, 3
+ NicCounter.add_item :Octets_tx, 4
+ NicCounter.add_item :Packets_rx, 5
+ NicCounter.add_item :Packets_tx, 6
+end
+
+class LoadCounter
+ def LoadCounter.add_item(key,value)
+ @hash ||= {}
+ @hash[key]=value
+ end
+
+ def LoadCounter.const_missing(key)
+ @hash[key]
+ end
+
+ def LoadCounter.each
+ @hash.each {|key,value| yield(key,value)}
+ end
+
+ def LoadCounter.getRRDPath(instance, counter)
+ path = "load/"
+ case counter
+ when LoadCounter::Load_1min, LoadCounter::Load_5min, LoadCounter::Load_15min
+ path += "load"
+ else
+ puts "Nothing"
+ end
+ return path
+ end
+
+ def LoadCounter.getRRDIndex(counter)
+ case counter
+ when LoadCounter::Load_1min
+ localIndex = 0
+ when LoadCounter::Load_5min
+ localIndex = 1
+ when LoadCounter::Load_15min
+ localIndex = 2
+ else
+ localIndex = 0
+ end
+
+ return localIndex
+ end
+
+ LoadCounter.add_item :Load_1min, 1
+ LoadCounter.add_item :Load_5min, 5
+ LoadCounter.add_item :Load_15min, 15
+end
+
+class RRDResolution
+ def RRDResolution.add_item(key,value)
+ @hash ||= {}
+ @hash[key]=value
+ end
+
+ def RRDResolution.const_missing(key)
+ @hash[key]
+ end
+
+ def RRDResolution.each
+ @hash.each {|key,value| yield(key,value)}
+ end
+
+ # Set up the resolutions for our rrd
+ RRDResolution.add_item :Default, 10 # Ten secs
+ RRDResolution.add_item :Short, 500 # 500 secs ( 8minute, 20 sec)
+ RRDResolution.add_item :Medium, 2230
+ RRDResolution.add_item :Long, 26500
+end
+
+
+
diff --git a/wui/src/app/util/stats/statsTest.rb b/wui/src/app/util/stats/statsTest.rb
index bf3bc60..f7ce612 100644
--- a/wui/src/app/util/stats/statsTest.rb
+++ b/wui/src/app/util/stats/statsTest.rb
@@ -23,43 +23,48 @@
# It shows some simple steps to build a request list and then
# request and process the data.
-require 'Stats'
+require 'util/stats/Stats'
# Retrieve the "idle" data for cpu0 from node3, node4, and node5
requestList = []
- requestList << StatsRequest.new("node3", "cpu", 0, "idle", 1211688000, 3600, 10 )
- requestList << StatsRequest.new("node4", "cpu", 0, "idle", 0, 3600, 10 )
- requestList << StatsRequest.new("node5", "cpu", 0, "idle", 1211688000, 3600, 500 )
- requestList << StatsRequest.new("node5", "memory", 0, "used", 0, 3600, 0 )
+# requestList << StatsRequest.new("node3.priv.ovirt.org", DevClass::Load, 0, LoadCounter::Load_1min, 0, 3600, 10 )
+# requestList << StatsRequest.new("node3.priv.ovirt.org", DevClass::Load, 0, LoadCounter::Load_1min, 0, 0, RRDResolution::Long )
+# requestList << StatsRequest.new("node3.priv.ovirt.org", DevClass::Load, 0, LoadCounter::Load_15min, 0, 0, RRDResolution::Long )
+# requestList << StatsRequest.new("node3.priv.ovirt.org", DevClass::NIC, 0, NicCounter::Octets_rx, 0, 0, RRDResolution::Long )
+# requestList << StatsRequest.new("node3.priv.ovirt.org", DevClass::NIC, 0, NicCounter::Octets_tx, 0, 0, RRDResolution::Long )
+ requestList << StatsRequest.new("node3.priv.ovirt.org", DevClass::Disk, 0, DiskCounter::Octets_read, 0, 0, RRDResolution::Long )
+ requestList << StatsRequest.new("node3.priv.ovirt.org", DevClass::Disk, 0, DiskCounter::Octets_write, 0, 0, RRDResolution::Long )
+# requestList << StatsRequest.new("node3.priv.ovirt.org", "cpu", 0, "idle", 1211688000, 3600, 10 )
+# requestList << StatsRequest.new("node4.priv.ovirt.org", DevClass::CPU, 0, CpuCounter::Idle, 0, 3600, RRDResolution::Short )
+# requestList << StatsRequest.new("node5.priv.ovirt.org", "cpu", 0, "idle", 1211688000, 3600, 500 )
+# requestList << StatsRequest.new("node5.priv.ovirt.org", DevClass::Memory, 0, MemCounter::Used, 0, 3600, 10 )
# Now send the request list and store the results in the statsList.
statsListBig = getStatsData?( requestList )
tmp = ""
- # Now lets loop through the returned list. It is a list of lists so take the first list
- # and chomp through it.
- #, pull off the statsData object and get the data from it.
+ # Now lets loop through the list, pull off the statsData object and get the data from it.
+ # Note that there is currently only one list sent back, so you need to check the node,
+ # device and counter for each to detect changes. We can look at using a list of lists
+ # if you think it is easier to process the results.
+# puts statsListBig.length
statsListBig.each do |statsList|
- # grab the data about this list, this will be consistent for all StatData objects in this list.
- myNodeName = statsList.get_node?()
- myDevClass = statsList.get_devClass?()
- myInstance = statsList.get_instance?()
- myCounter = statsList.get_counter?()
+ myNodeName = statsList.get_node?()
+ myDevClass = statsList.get_devClass?()
+ myInstance = statsList.get_instance?()
+ myCounter = statsList.get_counter?()
+
- # add a newline to break up data from different nodes for readability
if tmp != myNodeName then
puts
end
- # Now grab the data that is stored in the list
- # and loop through it. Note that we print it our directly
-
- list = statsList.get_data?()
- list.each do |d|
- print("\t", myNodeName, "\t", myDevClass, "\t", myInstance, "\t", myCounter, "\t",d.get_value?, "\t",d.get_timestamp?)
- puts
- end
+ list = statsList.get_data?()
+ list.each do |d|
+ print("\t", myNodeName, "\t", myDevClass, "\t", myInstance, "\t", myCounter, "\t",d.get_value?, "\t",d.get_timestamp?)
+ puts
+ end
tmp = myNodeName
end
diff --git a/wui/src/app/views/graph/history_graphs.rhtml b/wui/src/app/views/graph/history_graphs.rhtml
index 2f0026e..21b3efc 100644
--- a/wui/src/app/views/graph/history_graphs.rhtml
+++ b/wui/src/app/views/graph/history_graphs.rhtml
@@ -27,7 +27,7 @@
</div>
<div id="history_graphs_graphs">
<div class="history_graph" ><%= render :partial => '/layouts/graph', :locals => { :div_id => 'cpu_history', :chartType => 'line', :yGridLines => 'lightgrey', :url => (url_for :controller => 'graph', :action => 'history_graph_data', :id => @id, :target => 'cpu' ) } %></div>
- <div class="history_graph" ><%= render :partial => '/layouts/graph', :locals => { :div_id => 'io_history', :chartType => 'line', :yGridLines => 'lightgrey', :url => (url_for :controller => 'graph', :action => 'history_graph_data', :id => @id, :target => 'io' ) } %></div>
- <div class="history_graph" ><%= render :partial => '/layouts/graph', :locals => { :div_id => 'overall_load_history', :chartType => 'line', :yGridLines => 'lightgrey', :url => (url_for :controller => 'graph', :action => 'history_graph_data', :id => @id, :target => 'system' ) } %></div> -->
+ <div class="history_graph" ><%= render :partial => '/layouts/graph', :locals => { :div_id => 'memory_history', :chartType => 'line', :yGridLines => 'lightgrey', :url => (url_for :controller => 'graph', :action => 'history_graph_data', :id => @id, :target => 'memory' ) } %></div>
+ <div class="history_graph" ><%= render :partial => '/layouts/graph', :locals => { :div_id => 'load_history', :chartType => 'line', :yGridLines => 'lightgrey', :url => (url_for :controller => 'graph', :action => 'history_graph_data', :id => @id, :target => 'load' ) } %></div> -->
</div>
</div>
diff --git a/wui/src/app/views/graph/snapshot_graph.rhtml b/wui/src/app/views/graph/snapshot_graph.rhtml
index 2b8f58d..68d32f8 100644
--- a/wui/src/app/views/graph/snapshot_graph.rhtml
+++ b/wui/src/app/views/graph/snapshot_graph.rhtml
@@ -8,11 +8,11 @@
<tr>
<td>Overall Load </td>
<td>
- <div class="snapshot_graph_text"><%= @snapshots[:avg][:overall_load] %> </div>
+ <div class="snapshot_graph_text"><%= @snapshots[:avg]['load'] %> </div>
<div class="snapshot_graph_container">
- <div class="snapshot_graph_arrow" style="padding-left: <%= @snapshots[:peak][:overall_load] + 28 %>px;"><%= image_tag "icon_menu_arrow.gif" %></div>
+ <div class="snapshot_graph_arrow" style="padding-left: <%= @snapshots[:peak]['load'] + 28 %>px;"><%= image_tag "icon_menu_arrow.gif" %></div>
<div class="snapshot_graph">
- <%= render :partial => '/layouts/graph', :locals => { :div_id => 'overall_load_snapshot', :chartType => 'stackedRow', :url => (url_for :controller => 'graph', :action => 'snapshot_graph_data', :id => @id, :target => 'overall_load' ) } %>
+ <%= render :partial => '/layouts/graph', :locals => { :div_id => 'load_snapshot', :chartType => 'stackedRow', :url => (url_for :controller => 'graph', :action => 'snapshot_graph_data', :id => @id, :target => 'load' ) } %>
</div>
</div>
</td>
@@ -20,9 +20,9 @@
<tr>
<td>CPU </td>
<td>
- <div class="snapshot_graph_text"><%= @snapshots[:avg][:cpu] %> </div>
+ <div class="snapshot_graph_text"><%= @snapshots[:avg]['cpu'] %> </div>
<div class="snapshot_graph_container">
- <div class="snapshot_graph_arrow" style="padding-left: <%= @snapshots[:peak][:cpu] + 28 %>px;"><%= image_tag "icon_menu_arrow.gif" %></div>
+ <div class="snapshot_graph_arrow" style="padding-left: <%= @snapshots[:peak]['cpu'] + 28 %>px;"><%= image_tag "icon_menu_arrow.gif" %></div>
<div class="snapshot_graph">
<%= render :partial => '/layouts/graph', :locals => { :div_id => 'cpu_snapshot', :chartType => 'stackedRow', :url => (url_for :controller => 'graph', :action => 'snapshot_graph_data', :target => 'cpu' ) } %>
</div>
@@ -30,40 +30,40 @@
</td>
</tr>
<tr>
- <td>Network In </td>
+ <td>Memory </td>
<td>
- <div class="snapshot_graph_text"><%= @snapshots[:avg][:in] %> mb/s </div>
+ <div class="snapshot_graph_text"><%= @snapshots[:avg]['memory'] %> </div>
<div class="snapshot_graph_container">
- <div class="snapshot_graph_arrow" style="padding-left: <%= @snapshots[:peak][:in] + 28 %>px;"><%= image_tag "icon_menu_arrow.gif" %></div>
+ <div class="snapshot_graph_arrow" style="padding-left: <%= @snapshots[:peak]['memory'] + 28 %>px;"><%= image_tag "icon_menu_arrow.gif" %></div>
<div class="snapshot_graph">
- <%= render :partial => '/layouts/graph', :locals => { :div_id => 'net_in_snapshot', :chartType => 'stackedRow', :url => (url_for :controller => 'graph', :action => 'snapshot_graph_data', :target => 'in' ) } %>
+ <%= render :partial => '/layouts/graph', :locals => { :div_id => 'memory_snapshot', :chartType => 'stackedRow', :url => (url_for :controller => 'graph', :action => 'snapshot_graph_data', :target => 'memory' ) } %>
</div>
</div>
</td>
</tr>
<tr>
- <td>Network Out</td>
+ <td>Network In </td>
<td>
- <div class="snapshot_graph_text"><%= @snapshots[:avg][:out] %> mb/s</div>
+ <div class="snapshot_graph_text"><%= @snapshots[:avg]['netin'] %> mb/s </div>
<div class="snapshot_graph_container">
- <div class="snapshot_graph_arrow" style="padding-left: <%= @snapshots[:peak][:out] + 28 %>px;"><%= image_tag "icon_menu_arrow.gif" %></div>
+ <div class="snapshot_graph_arrow" style="padding-left: <%= @snapshots[:peak]['netin'] + 28 %>px;"><%= image_tag "icon_menu_arrow.gif" %></div>
<div class="snapshot_graph">
- <%= render :partial => '/layouts/graph', :locals => { :div_id => 'net_out_snapshot', :chartType => 'stackedRow', :url => (url_for :controller => 'graph', :action => 'snapshot_graph_data', :target => 'out' ) } %>
+ <%= render :partial => '/layouts/graph', :locals => { :div_id => 'net_in_snapshot', :chartType => 'stackedRow', :url => (url_for :controller => 'graph', :action => 'snapshot_graph_data', :target => 'netin' ) } %>
</div>
</div>
</td>
</tr>
<tr>
- <td>I/O </td>
+ <td>Network Out</td>
<td>
- <div class="snapshot_graph_text"><%= @snapshots[:avg][:io] %> mb/s</div>
+ <div class="snapshot_graph_text"><%= @snapshots[:avg]['netout'] %> mb/s</div>
<div class="snapshot_graph_container">
- <div class="snapshot_graph_arrow" style="padding-left: <%= @snapshots[:peak][:io] + 28 %>px;"><%= image_tag "icon_menu_arrow.gif" %></div>
+ <div class="snapshot_graph_arrow" style="padding-left: <%= @snapshots[:peak]['netout'] + 28 %>px;"><%= image_tag "icon_menu_arrow.gif" %></div>
<div class="snapshot_graph">
- <%= render :partial => '/layouts/graph', :locals => { :div_id => 'io_snapshot', :chartType => 'stackedRow', :url => (url_for :controller => 'graph', :action => 'snapshot_graph_data', :target => 'io' ) } %> </td>
+ <%= render :partial => '/layouts/graph', :locals => { :div_id => 'net_out_snapshot', :chartType => 'stackedRow', :url => (url_for :controller => 'graph', :action => 'snapshot_graph_data', :target => 'netout' ) } %>
</div>
</div>
- </td>
+ </td>
</tr>
</table>
</div>
diff --git a/wui/src/app/views/host/_grid.rhtml b/wui/src/app/views/host/_grid.rhtml
index 0ce2a06..a3cac7c 100644
--- a/wui/src/app/views/host/_grid.rhtml
+++ b/wui/src/app/views/host/_grid.rhtml
@@ -11,6 +11,7 @@
(
{
url: '<%= url_for :controller => "hardware", :action => "hosts_json", :id => (hwpool.nil? ? nil : hwpool.id), :exclude_id => exclude_id %>',
+ url: '<%= url_for :controller => "hardware", :action => "hosts_json", :id => (hwpool.nil? ? nil : hwpool.id), :exclude_id => exclude_id %>',
dataType: 'json',
colModel : [
{display: '', width : 20, align: 'left', process: <%= table_id %>checkbox},
@@ -27,8 +28,8 @@
],
sortname: "hostname",
sortorder: "asc",
- usepager: <%= (!hwpool.nil? and hwpool.hosts.size > hosts_per_page) ? 'true' : 'false' %>,
- useRp: <%= (!hwpool.nil? and hwpool.hosts.size > hosts_per_page) ? 'true' : 'false' %>,
+ usepager: <%= (!hwpool.nil? and hwpool.hosts.size > hosts_per_page) ? 'true' : 'false' %>,
+ useRp: <%= (!hwpool.nil? and hwpool.hosts.size > hosts_per_page) ? 'true' : 'false' %>,
rp: <%= hosts_per_page %>,
showTableToggleBtn: true,
onSelect: <%= on_select %>,
diff --git a/wui/src/app/views/storage/_grid.rhtml b/wui/src/app/views/storage/_grid.rhtml
index 15a0331..843d64d 100644
--- a/wui/src/app/views/storage/_grid.rhtml
+++ b/wui/src/app/views/storage/_grid.rhtml
@@ -9,7 +9,7 @@
$("#<%= table_id %>").flexigrid
(
{
- url: '<%= url_for :controller => "hardware", :action => "storage_pools_json", :id => (hwpool.nil? ? nil : hwpool.id), :exclude_id => exclude_id %>',
+ url: '<%= url_for :controller => "hardware", :action => "storage_pools_json", :id => (hwpool.nil? ? nil : hwpool.id), :exclude_id => exclude_id %>',
dataType: 'json',
colModel : [
{display: '', width : 20, align: 'left', process: <%= table_id %>checkbox},
@@ -20,8 +20,8 @@
],
sortname: "ip_addr",
sortorder: "asc",
- usepager: <%= (!hwpool.nil? and hwpool.storage_pools.size > storage_per_page) ? 'true' : 'false' %>,
- useRp: <%= (!hwpool.nil? and hwpool.storage_pools.size > storage_per_page) ? 'true' : 'false' %>,
+ usepager: <%= (!hwpool.nil? and hwpool.storage_pools.size > storage_per_page) ? 'true' : 'false' %>,
+ useRp: <%= (!hwpool.nil? and hwpool.storage_pools.size > storage_per_page) ? 'true' : 'false' %>,
rp: <%= storage_per_page %>,
showTableToggleBtn: true,
onSelect: <%= on_select %>
diff --git a/wui/src/app/views/storage/addstorage.html.erb b/wui/src/app/views/storage/addstorage.html.erb
index 0fb3ce1..fa49111 100644
--- a/wui/src/app/views/storage/addstorage.html.erb
+++ b/wui/src/app/views/storage/addstorage.html.erb
@@ -31,7 +31,7 @@
<div class="panel_header"></div>
<div class="dialog_body">
<%= render :partial => "/storage/grid", :locals => { :table_id => "addstorage_grid",
- :hwpool => nil, :exclude_id => @hardware_pool.id,
+ :hwpool => nil, :exclude_id => @hardware_pool.id,
:on_select => "false" } %>
</div>
</div>
diff --git a/wui/src/app/views/vm/_grid.rhtml b/wui/src/app/views/vm/_grid.rhtml
index b0fc71a..c56e6b8 100644
--- a/wui/src/app/views/vm/_grid.rhtml
+++ b/wui/src/app/views/vm/_grid.rhtml
@@ -24,7 +24,7 @@
sortname: "description",
sortorder: "asc",
usepager: <%= pool.vms.size > vms_per_page ? 'true' : 'false' %>,
- useRp: <%= pool.vms.size > vms_per_page ? 'true' : 'false' %>,
+ useRp: <%= pool.vms.size > vms_per_page ? 'true' : 'false' %>,
rp: <%= vms_per_page %>,
showTableToggleBtn: true,
onSelect: <%= on_select %>,
diff --git a/wui/src/public/stylesheets/components.css b/wui/src/public/stylesheets/components.css
index 30730da..e2bc235 100644
--- a/wui/src/public/stylesheets/components.css
+++ b/wui/src/public/stylesheets/components.css
@@ -190,7 +190,7 @@
position: relative;
float: left;
}
-#cpu_history, #io_history, #overall_load_history{
+#cpu_history, #io_history, #load_history, #memory_history{
height: 200px; width: 1200px; position: absolute; left: -70px;
}
@@ -199,7 +199,7 @@
#snapshot_graphs table { width: 90%; border-spacing: 0;}
#snapshot_graphs th { background: #CCCCCC; text-align: left; padding-left: 10px; border: 1px solid #DDDDDD;}
#snapshot_graphs td { padding-left: 10px; border: 1px solid #DDDDDD;}
-#overall_load_snapshot, #cpu_snapshot, #net_in_snapshot, #net_out_snapshot, #io_snapshot {
+#load_snapshot, #cpu_snapshot, #net_in_snapshot, #net_out_snapshot, #io_snapshot, #memory_snapshot {
width: 350px; height: 20px; float: left;
}
.snapshot_graph_text {
--
1.5.4.1
More information about the ovirt-devel
mailing list