Steve Linabery
2008-Sep-17 21:04 UTC
[Ovirt-devel] [PATCH server] Add max/min methods to stats results, various other fixes to stats
>From df0bb94ed5549ab6826da255f9acca5e414938aa Mon Sep 17 00:00:00 2001From: Steve Linabery <slinabery at redhat.com> Date: Wed, 17 Sep 2008 15:22:39 -0500 Subject: [PATCH] Add max/min methods to stats results, various other fixes to stats --- src/app/util/stats/Stats.rb | 64 +++++++++++++++++++++++++++++++---- src/app/util/stats/StatsDataList.rb | 28 +++++++++++++-- src/app/util/stats/statsTest.rb | 38 +++++++++++++------- 3 files changed, 107 insertions(+), 23 deletions(-) diff --git a/src/app/util/stats/Stats.rb b/src/app/util/stats/Stats.rb index f6ced4b..b434232 100644 --- a/src/app/util/stats/Stats.rb +++ b/src/app/util/stats/Stats.rb @@ -29,6 +29,8 @@ require 'util/stats/StatsRequest' def fetchRollingAve?(rrdPath, start, endTime, interval, myFunction, lIndex, returnList, aveLen=7) final = 0 + my_min = 0 + my_max = 0 # OK, first thing we need to do is to move the start time back in order to # have data to average. @@ -65,19 +67,32 @@ def fetchRollingAve?(rrdPath, start, endTime, interval, myFunction, lIndex, retu final += rdata end final = (final / aveLen ) + + # Determine min / max to help with autoscale. + unless final.is_a? (Float) && final.nan? + my_min = [my_min, final].min + my_max = [my_max, final].max + end returnList.append_data( StatsData.new(fstart + interval * ( i - indexOffset), final )) # Now shift the head off the array roll.shift end end - + + # Now add the min / max to the lists + returnList.set_min_value(my_min) + returnList.set_max_value(my_max) + return returnList end def fetchRollingCalcUsedData?(rrdPath, start, endTime, interval, myFunction, lIndex, returnList, aveLen=7) + my_min = 0 + my_max = 0 + # OK, first thing we need to do is to move the start time back in order to have data to average. indexOffset = ( aveLen / 2 ).to_i @@ -120,12 +135,22 @@ def fetchRollingCalcUsedData?(rrdPath, start, endTime, interval, myFunction, lIn final += rdata end final = (final / aveLen) + + # Determine min / max to help with autoscale. + unless final.is_a? (Float) && final.nan? + my_min = [my_min, final].min + my_max = [my_max, final].max + end returnList.append_data( StatsData.new(fstart + interval * ( i - indexOffset), final )) # Now shift the head off the array roll.shift end end + # Now add the min / max to the lists + returnList.set_min_value(my_min) + returnList.set_max_value(my_max) + return returnList end @@ -137,6 +162,9 @@ def fetchCalcUsedData?(rrdPath, start, endTime, interval, myFunction, lIndex, re # We also need to handle NaN differently # Finally, we need to switch Min and Max + my_min = 0 + my_max = 0 + lFunc = "AVERAGE" case myFunction when "MAX" @@ -155,13 +183,23 @@ def fetchCalcUsedData?(rrdPath, start, endTime, interval, myFunction, lIndex, re data.each do |vdata| i += 1 value = vdata[lIndex] - value = 100 if value.nan? - if ( value > 100 ) - value = 100 - end - value = 100 - value + value = 100 if value.nan? + if ( value > 100 ) + value = 100 + end + value = 100 - value + + # Determine min / max to help with autoscale. + unless value.is_a? (Float) && value.nan? + my_min = [my_min, value].min + my_max = [my_max, value].max + end returnList.append_data( StatsData.new(fstart + interval * i, value )) end + + # Now add the min / max to the lists + returnList.set_min_value(my_min) + returnList.set_max_value(my_max) return returnList end @@ -169,6 +207,9 @@ end def fetchRegData?(rrdPath, start, endTime, interval, myFunction, lIndex, returnList) + my_min = 0 + my_max = 0 + (fstart, fend, names, data, interval) = RRD.fetch(rrdPath, "--start", start.to_s, "--end", \ endTime.to_s, myFunction, "-r", interval.to_s) i = 0 @@ -177,9 +218,18 @@ def fetchRegData?(rrdPath, start, endTime, interval, myFunction, lIndex, returnL # Now, lets walk the returned data and create the ojects, and put them in a list. data.each do |vdata| + value = vdata[lIndex] i += 1 - returnList.append_data( StatsData.new(fstart + interval * i, vdata[lIndex] )) + unless value.is_a? (Float) && value.nan? + my_min = [my_min, value].min + my_max = [my_max, value].max + end + returnList.append_data( StatsData.new(fstart + interval * i, value )) end + + # Now add the min / max to the lists + returnList.set_min_value(my_min) + returnList.set_max_value(my_max) return returnList end diff --git a/src/app/util/stats/StatsDataList.rb b/src/app/util/stats/StatsDataList.rb index d6de29c..a39bcc4 100644 --- a/src/app/util/stats/StatsDataList.rb +++ b/src/app/util/stats/StatsDataList.rb @@ -29,13 +29,19 @@ class StatsDataList @data=[] @status = status @function = function - end + @min_value = 0 + @max_value = 0 + end def get_node?() return @node end - def get_devClass?() + def get_node?() + return @node + end + + def get_devClass?() return @devClass end @@ -66,4 +72,20 @@ class StatsDataList def length() return @data.length end -end + + def set_min_value(min) + @min_value = min + end + + def set_max_value(max) + @max_value = max + end + + def get_min_value?() + return @min_value + end + + def get_max_value?() + return @max_value + end +end diff --git a/src/app/util/stats/statsTest.rb b/src/app/util/stats/statsTest.rb index baedbc0..007bb71 100644 --- a/src/app/util/stats/statsTest.rb +++ b/src/app/util/stats/statsTest.rb @@ -33,11 +33,20 @@ require 'util/stats/Stats' # requestList << StatsRequest.new("node3.priv.ovirt.org", DevClass::Load, 0, LoadCounter::Load_15min, 0, 0, RRDResolution::Long ) # requestList << StatsRequest.new("node7.priv.ovirt.org", DevClass::NIC, 0, NicCounter::Octets_rx, 0, 0, RRDResolution::Long ) # requestList << StatsRequest.new("node3.priv.ovirt.org", DevClass::NIC, 1, NicCounter::Octets_rx, 0, 0, RRDResolution::Long ) - requestList << StatsRequest.new("node3.priv.ovirt.org", DevClass::NIC, 0, NicCounter::Octets_tx, 0, 604800, RRDResolution::Medium ) +# requestList << StatsRequest.new("node5.priv.ovirt.org", DevClass::NIC, 0, NicCounter::Octets_tx, 0, 604800, RRDResolution::Long, DataFunction::Average ) +# requestList << StatsRequest.new("node5.priv.ovirt.org", DevClass::NIC, 0, NicCounter::Octets_tx, 0, 604800, RRDResolution::Long, DataFunction::Peak ) +# requestList << StatsRequest.new("node5.priv.ovirt.org", DevClass::NIC, 0, NicCounter::Octets_tx, 0, 604800, 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("node3.priv.ovirt.org", DevClass::CPU, 0, CpuCounter::CalcUsed, 0, 300, RRDResolution::Default, DataFunction::Average ) + requestList << StatsRequest.new("node3.priv.ovirt.org", DevClass::NIC, 0, NicCounter::Octets_rx, 0, 0, RRDResolution::Default ) +# requestList << StatsRequest.new("node3.priv.ovirt.org", DevClass::CPU, 0, CpuCounter::Idle, 0, 300, RRDResolution::Default, DataFunction::RollingAverage ) +# requestList << StatsRequest.new("node3.priv.ovirt.org", DevClass::CPU, 0, CpuCounter::Idle, 0, 300, RRDResolution::Default, DataFunction::Average ) + requestList << StatsRequest.new("node3.priv.ovirt.org", DevClass::CPU, 0, CpuCounter::CalcUsed, 0, 300, RRDResolution::Default, DataFunction::RollingAverage ) +# requestList << StatsRequest.new("node4.priv.ovirt.org", DevClass::CPU, 0, CpuCounter::Idle, 0, 3600, RRDResolution::Short, DataFunction::Average ) +# requestList << StatsRequest.new("node4.priv.ovirt.org", DevClass::CPU, 0, CpuCounter::CalcUsed, 0, 3600, RRDResolution::Short, DataFunction::Min ) # 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 ) @@ -58,21 +67,24 @@ require 'util/stats/Stats' myCounter = statsList.get_counter?() myStatus = statsList.get_status?() - case myStatus - when StatsStatus::E_NOSUCHNODE - puts "Can't find data for node " + myNodeName - when StatsStatus::E_UNKNOWN - puts "Can't find data for requested file path" - end - if tmp != myNodeName then + case myStatus + when StatsStatus::E_NOSUCHNODE + puts "Can't find data for node " + myNodeName + when StatsStatus::E_UNKNOWN + puts "Can't find data for requested file path" + end + if tmp != myNodeName then + 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 - 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 + print("\tmin_value is: ", statsList.get_min_value?(), "\tmax_value is: ", statsList.get_max_value?()) + puts end -- 1.5.5.1
Jim Meyering
2008-Sep-18 15:03 UTC
[Ovirt-devel] [PATCH server] Add max/min methods to stats results, various other fixes to stats
Steve Linabery <slinabery at redhat.com> wrote:>>From df0bb94ed5549ab6826da255f9acca5e414938aa Mon Sep 17 00:00:00 2001 > From: Steve Linabery <slinabery at redhat.com> > Date: Wed, 17 Sep 2008 15:22:39 -0500 > Subject: [PATCH] Add max/min methods to stats results, various other fixes to stats > > --- > src/app/util/stats/Stats.rb | 64 +++++++++++++++++++++++++++++++---- > src/app/util/stats/StatsDataList.rb | 28 +++++++++++++-- > src/app/util/stats/statsTest.rb | 38 +++++++++++++------- > 3 files changed, 107 insertions(+), 23 deletions(-)ACK, comments below.> diff --git a/src/app/util/stats/Stats.rb b/src/app/util/stats/Stats.rb > index f6ced4b..b434232 100644 > --- a/src/app/util/stats/Stats.rb > +++ b/src/app/util/stats/Stats.rb > @@ -29,6 +29,8 @@ require 'util/stats/StatsRequest' > > def fetchRollingAve?(rrdPath, start, endTime, interval, myFunction, lIndex, returnList, aveLen=7) > final = 0 > + my_min = 0 > + my_max = 0 > > # OK, first thing we need to do is to move the start time back in order to > # have data to average. > @@ -65,19 +67,32 @@ def fetchRollingAve?(rrdPath, start, endTime, interval, myFunction, lIndex, retu > final += rdata > end > final = (final / aveLen ) > + > + # Determine min / max to help with autoscale. > + unless final.is_a? (Float) && final.nan? > + my_min = [my_min, final].min > + my_max = [my_max, final].max > + end > returnList.append_data( StatsData.new(fstart + interval * ( i - indexOffset), final )) > > # Now shift the head off the array > roll.shift > end > end > - > + > + # Now add the min / max to the lists > + returnList.set_min_value(my_min) > + returnList.set_max_value(my_max) > + > return returnList > end > > > def fetchRollingCalcUsedData?(rrdPath, start, endTime, interval, myFunction, lIndex, returnList, aveLen=7) > > + my_min = 0 > + my_max = 0 > + > # OK, first thing we need to do is to move the start time back in order to have data to average. > > indexOffset = ( aveLen / 2 ).to_i > @@ -120,12 +135,22 @@ def fetchRollingCalcUsedData?(rrdPath, start, endTime, interval, myFunction, lIn > final += rdata > end > final = (final / aveLen) > + > + # Determine min / max to help with autoscale. > + unless final.is_a? (Float) && final.nan? > + my_min = [my_min, final].min > + my_max = [my_max, final].max > + end > returnList.append_data( StatsData.new(fstart + interval * ( i - indexOffset), final )) > # Now shift the head off the array > roll.shift > end > end > > + # Now add the min / max to the lists > + returnList.set_min_value(my_min) > + returnList.set_max_value(my_max) > + > return returnList > end > > @@ -137,6 +162,9 @@ def fetchCalcUsedData?(rrdPath, start, endTime, interval, myFunction, lIndex, re > # We also need to handle NaN differently > # Finally, we need to switch Min and Max > > + my_min = 0 > + my_max = 0 > + > lFunc = "AVERAGE" > case myFunction > when "MAX" > @@ -155,13 +183,23 @@ def fetchCalcUsedData?(rrdPath, start, endTime, interval, myFunction, lIndex, re > data.each do |vdata| > i += 1 > value = vdata[lIndex] > - value = 100 if value.nan? > - if ( value > 100 ) > - value = 100 > - end > - value = 100 - value > + value = 100 if value.nan? > + if ( value > 100 ) > + value = 100 > + end > + value = 100 - valueNo need for the value.nan? test here, since it's handled just above, but it may be just as well to leave it for consistency with the other, similar uses.> + # Determine min / max to help with autoscale. > + unless value.is_a? (Float) && value.nan? > + my_min = [my_min, value].min > + my_max = [my_max, value].max > + end > returnList.append_data( StatsData.new(fstart + interval * i, value )) > endA thought for later (not to hold up this review): rather than imposing that repetitive (and relatively subtle) NaN test everywhere, is there some place central where you deal with any incoming NaN values up front so code like this can assume sanitized values? IMHO, that'd be more maintainable. Otherwise, every comparison involving those data will have to think hard how to handle NaNs.