The environment in which the post processors are evaluated. Every method defined here is available in the post_process block and run! methods of the predefined post processors
Resets the whole post processor environment
# File lib/bigbench/post_processor/environment.rb, line 9 def self.reset! @@clusters, @@statistics, @@normal_distribution, @@regressions, @@appearings = {}, {}, {}, {}, {} @@trackings = [] @@scope = :all end
Returns an array of appearing attributes in the selected tracking scope.
appearing.statuses # => [200, 404] appearing.methods # => ["get", "post"] appearing.paths # => ["/", "/basic/auth"
# File lib/bigbench/post_processor/environment.rb, line 143 def appearing(timebase = 1.second) return @@appearings[scope] unless @@appearings[scope].nil? @@appearings[scope] ||= Appearings.new(scope) end
Returns a clustered overview of all trackings. By default the trackings are clustered by second, but you can also specify any ammount of seconds to group together. A cluster then has the following methods:
# Duration was 120 seconds cluster.timesteps # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,..., 120] (seconds) cluster.durations # => [50.3, 51.2, 40.3, 51.3, 50.3, 55.3, 52.3, 50.3, 51.3, 50.3, 54.3,..., 50.3] (average duration in milliseconds) cluster.requests # => [580, 569, 540, 524, 524, 525, 528, 520, 529, 527, 523,..., 524] (requests in that second) cluster.methods(:get) # => [400, 509, 340, 424, 324, 525, 528, 520, 529, 527, 523,..., 524] (GET requests in that second) cluster.methods(:post) # => [400, 509, 340, 424, 324, 525, 528, 520, 529, 527, 523,..., 524] (POST requests in that second) cluster.statuses(200) # => [400, 509, 340, 424, 324, 525, 528, 520, 529, 527, 523,..., 524] (successful - requests in that second) cluster.statuses(404) # => [400, 509, 340, 424, 324, 525, 528, 520, 529, 527, 523,..., 524] (not founds - requests in that second) cluster.paths("/") # => [400, 509, 340, 424, 324, 525, 528, 520, 529, 527, 523,..., 524] (requests to a path in that second) cluster.paths("/home") # => [400, 509, 340, 424, 324, 525, 528, 520, 529, 527, 523,..., 524] (requests to "/home" path in that second) cluster.benchmark("index") # => [400, 509, 340, 424, 324, 525, 528, 520, 529, 527, 523,..., 524] (requests from the index benchmark in that second) cluster.benchmark("user") # => [400, 509, 340, 424, 324, 525, 528, 520, 529, 527, 523,..., 524] (requests from the user benchmark in that second) # Duration was 120 seconds = 2 minutes cluster(1.minute).timesteps # => [0, 1] (minutes) cluster(1.minute).durations # => [50.3, 51.2] (average duration in milliseconds) cluster(1.minute).requests # => [27836, 27684] (requests in that minute)
# File lib/bigbench/post_processor/environment.rb, line 129 def cluster(timebase = 1.second, extra_scope = nil) cluster_scope = extra_scope || scope timebase_and_scope = [timebase.to_i, cluster_scope] return @@clusters[timebase_and_scope] unless @@clusters[timebase_and_scope].nil? @@clusters[timebase_and_scope] = Cluster.new(timebase, cluster_scope) end
Iterates over all benchmarks and automatically executes all methods in the benchmark scope like this:
# For all benchmarks cluster.durations cluster.requests # For each benchmark each_benchmark do |benchmark| cluster.durations cluster.requests end
# File lib/bigbench/post_processor/environment.rb, line 100 def each_benchmark BigBench.benchmarks.each do |benchmark| scope_to_benchmark(benchmark.name) do yield benchmark end end end
Iterates through every tracking and returns a tracking hash of the following form:
{ :elapsed => 2.502132, :start => 1333986292.1755981, :stop => 1333986293.618884, :duration => 1443, :benchmark => "index page", :url => "http://www.google.de/", :path => "/", :method => "get", :status => 200 }
# File lib/bigbench/post_processor/environment.rb, line 54 def each_tracking File.open(BigBench.config.output, "r+") do |file| file.each_line { |line| yield JSON.parse(line).inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo} unless line.blank? } end end
Returns a gaussian distribution for the specified attribute. It automatically calculates the neccessary mean and variance values and adapts the x values to fit the bell curve best.
normal_distribution.durations.x # => [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, ...] normal_distribution.durations.y # => [0, 0, 7, 8, 9, 10, 11, 10, 9, 8, 7, 4, ...]
# File lib/bigbench/post_processor/environment.rb, line 186 def normal_distribution(timebase = 1.second) timebase_and_scope = [timebase.to_i, scope] return @@normal_distribution[timebase_and_scope] unless @@normal_distribution[timebase_and_scope].nil? @@normal_distribution[timebase_and_scope] ||= AttributeCluster.new(NormalDistribution, :timebase => timebase, :scope => scope) # Duration is the only value that shouldn't be clustered in the statistics because we have real float values in it, and do not only count +1 # for the request. Because of this, we'll exchange the clustered durations y values with an array of all unclustered tracking durations @@normal_distribution[timebase_and_scope].instance_eval do @durations.instance_eval do @y = trackings.map{ |tracking| tracking[:duration] if tracking[:benchmark] == scope or scope == :all }.compact end end @@normal_distribution[timebase_and_scope] end
Returns a polynomial regression of a degree, a derivation and a timebase. Possible options are:
[:degree] By default the degree is 1 which results in a linear regression. There's no limit to the degree. [:derivation] By default the normal function, which means no derivation is returned. Currently only the first derivation is supported. [:timebase] By default the cluster size is 1.second. Any timelimit can be added here, e.g. 1.minute # Return a linear regression for the durations, clustered by seconds polynomial_regression.durations.y polynomial_regression(:degree => 1, :timebase => 1.second).durations.y polynomial_regression(:degree => 1, :timebase => 1.second).durations.derivation(0) # Return the first derivation of the linear regression for the durations, clustered by seconds polynomial_regression(:degree => 1).durations.derivation(1) polynomial_regression(:degree => 1, :timebase => 1.second).durations.derivation(1) # Return a second degree polynomial regression for the durations, clustered by seconds polynomial_regression(:degree => 2).durations.derivation(0) polynomial_regression(:degree => 2, :timebase => 1.second).durations.derivation(0) # Return the first derivation of the second degree polynomial regression for the durations, clustered by seconds polynomial_regression(:degree => 2).durations.derivation(0) polynomial_regression(:degree => 2, :timebase => 1.second).durations.derivation(0)
# File lib/bigbench/post_processor/environment.rb, line 227 def polynomial_regression(new_options = {}) options = { :degree => 1, :timebase => 1.second }.merge(new_options) degree_and_timebase_and_scope = [options[:degree], options[:timebase].to_i, scope] return @@regressions[degree_and_timebase_and_scope] unless @@regressions[degree_and_timebase_and_scope].nil? @@regressions[degree_and_timebase_and_scope] ||= AttributeCluster.new(PolynomialRegression, :timebase => options[:timebase], :scope => scope, :degree => options[:degree]) end
Returns the current scope the environment works in
# File lib/bigbench/post_processor/environment.rb, line 69 def scope @@scope end
Executes the including methods in the scope of the benchmark:
# For the "index page" benchmark scope_to_benchmark "index page" do cluster.durations cluster.requests end
# File lib/bigbench/post_processor/environment.rb, line 81 def scope_to_benchmark name raise BenchmarkNotFound.new(name) unless BigBench.benchmarks.map{|b| b.name }.include?(name) @@scope = name yield @@scope = nil end
Returns the default statistics for a given attribute. The following statistics are available:
statistics.durations.max # => 78.2 statistics.durations.min # => 12.3 statistics.durations.mean # => 45.2 statistics.durations.average # => 45.2 statistics.durations.standard_deviation # => 11.3 statistics.durations.sd # => 11.3 statistics.durations.squared_deviation # => 60.7 statistics.durations.variance # => 60.7
# File lib/bigbench/post_processor/environment.rb, line 163 def statistics(timebase = 1.second) timebase_and_scope = [timebase.to_i, scope] return @@statistics[timebase_and_scope] unless @@statistics[timebase_and_scope].nil? @@statistics[timebase_and_scope] ||= AttributeCluster.new(Statistics, :timebase => timebase, :scope => scope) # Duration is the only value that shouldn't be clustered in the statistics because we have real float values in it, and do not only count +1 # for the request. Because of this, we'll exchange the clustered durations y values with an array of all unclustered tracking durations @@statistics[timebase_and_scope].instance_eval do @durations.instance_eval do @y = trackings.map{ |tracking| tracking[:duration] if tracking[:benchmark] == scope or scope == :all }.compact end end @@statistics[timebase_and_scope] end
Puts all tracking hashes into a huge array. Warning, this method call might
take quite long! The results are cached, so you can call
trackings
in the future without any pain
# File lib/bigbench/post_processor/environment.rb, line 62 def trackings return @@trackings unless @@trackings.empty? each_tracking{ |tracking| @@trackings << tracking } @@trackings end