class MCollective::RPC::Stats
Class to wrap all the stats and to keep track of some timings
Attributes
Public Class Methods
# File lib/mcollective/rpc/stats.rb 9 def initialize 10 reset 11 end
Public Instance Methods
Fake hash access to keep things backward compatible
# File lib/mcollective/rpc/stats.rb 51 def [](key) 52 to_hash[key] 53 rescue 54 nil 55 end
Re-initializes the object with stats from the basic client
# File lib/mcollective/rpc/stats.rb 72 def client_stats=(stats) 73 @noresponsefrom = stats[:noresponsefrom] 74 @unexpectedresponsefrom = stats[:unexpectedresponsefrom] 75 @responses = stats[:responses] 76 @starttime = stats[:starttime] 77 @blocktime = stats[:blocktime] 78 @totaltime = stats[:totaltime] 79 @requestid = stats[:requestid] 80 @discoverytime = stats[:discoverytime] if @discoverytime == 0 81 end
Update discovered and discovered_nodes
based on discovery results
# File lib/mcollective/rpc/stats.rb 111 def discovered_agents(agents) 112 @discovered_nodes = agents 113 @discovered = agents.size 114 end
increment the count of failed hosts
# File lib/mcollective/rpc/stats.rb 65 def fail 66 @failcount += 1 67 rescue 68 @failcount = 1 69 end
Helper to calculate total time etc
# File lib/mcollective/rpc/stats.rb 117 def finish_request 118 @totaltime = @blocktime + @discoverytime 119 120 # figure out who responded unexpectedly 121 @unexpectedresponsefrom = @responsesfrom - @discovered_nodes 122 123 # figure out who we had no responses from 124 @noresponsefrom = @discovered_nodes - @responsesfrom 125 rescue 126 @totaltime = 0 127 @noresponsefrom = [] 128 @unexpectedresponsefrom = [] 129 end
Returns a blob of text indicating what nodes did not respond
# File lib/mcollective/rpc/stats.rb 254 def no_response_report 255 result_text = StringIO.new 256 257 if @noresponsefrom.size > 0 258 result_text.puts Util.colorize(:red, "No response from:") 259 result_text.puts 260 261 field_size = Util.field_size(@noresponsefrom, 30) 262 fields_num = Util.field_number(field_size) 263 format = " " + ( " %-#{field_size}s" * fields_num ) 264 265 @noresponsefrom.sort.in_groups_of(fields_num) do |c| 266 result_text.puts format % c 267 end 268 end 269 270 result_text.string 271 end
Helper to keep track of who we received responses from
# File lib/mcollective/rpc/stats.rb 132 def node_responded(node) 133 @responsesfrom << node 134 rescue 135 @responsesfrom = [node] 136 end
increment the count of ok hosts
# File lib/mcollective/rpc/stats.rb 58 def ok 59 @okcount += 1 60 rescue 61 @okcount = 1 62 end
Returns a blob of text representing the request status based on the stats contained in this class
# File lib/mcollective/rpc/stats.rb 190 def report(caption = "rpc stats", summarize = true, verbose = false) 191 result_text = [] 192 193 if verbose 194 if @aggregate_summary.size > 0 && summarize 195 result_text << text_for_aggregates 196 else 197 result_text << "" 198 end 199 200 result_text << Util.colorize(:yellow, "---- #{caption} ----") 201 202 if @discovered 203 @responses < @discovered ? color = :red : color = :reset 204 result_text << " Nodes: %s / %s" % [ Util.colorize(color, @discovered), Util.colorize(color, @responses) ] 205 else 206 result_text << " Nodes: #{@responses}" 207 end 208 209 @failcount < 0 ? color = :red : color = :reset 210 211 result_text << " Pass / Fail: %s / %s" % [Util.colorize(color, @okcount), Util.colorize(color, @failcount) ] 212 result_text << " Start Time: %s" % [Time.at(@starttime)] 213 result_text << " Discovery Time: %.2fms" % [@discoverytime * 1000] 214 result_text << " Agent Time: %.2fms" % [@blocktime * 1000] 215 result_text << " Total Time: %.2fms" % [@totaltime * 1000] 216 else 217 if @discovered 218 @responses < @discovered ? color = :red : color = :green 219 220 if @aggregate_summary.size + @aggregate_failures.size > 0 && summarize 221 result_text << text_for_aggregates 222 else 223 result_text << "" 224 end 225 226 result_text << "Finished processing %s / %s hosts in %.2f ms" % [Util.colorize(color, @responses), Util.colorize(color, @discovered), @blocktime * 1000] 227 else 228 result_text << "Finished processing %s hosts in %.2f ms" % [Util.colorize(:bold, @responses), @blocktime * 1000] 229 end 230 end 231 232 no_response_r = no_response_report 233 unexpected_response_r = unexpected_response_report 234 if no_response_r || unexpected_response_r 235 result_text << "" 236 end 237 238 if no_response_r != "" 239 result_text << "" << no_response_r 240 end 241 242 if unexpected_response_r != "" 243 result_text << "" << unexpected_response_r 244 end 245 246 if no_response_r || unexpected_response_r 247 result_text << "" 248 end 249 250 result_text.join("\n") 251 end
Resets stats, if discovery time is set we keep it as it was
# File lib/mcollective/rpc/stats.rb 14 def reset 15 @noresponsefrom = [] 16 @unexpectedresponsefrom = [] 17 @responsesfrom = [] 18 @responses = 0 19 @starttime = Time.now.to_f 20 @discoverytime = 0 unless @discoverytime 21 @blocktime = 0 22 @totaltime = 0 23 @discovered = 0 24 @discovered_nodes = [] 25 @okcount = 0 26 @failcount = 0 27 @requestid = nil 28 @aggregate_summary = [] 29 @aggregate_failures = [] 30 end
# File lib/mcollective/rpc/stats.rb 138 def text_for_aggregates 139 result = StringIO.new 140 141 @aggregate_summary.each do |aggregate| 142 output_item = aggregate.result[:output] 143 144 begin 145 action_interface = @ddl.action_interface(aggregate.action) 146 display_as = action_interface[:output][output_item][:display_as] 147 rescue 148 display_as = output_item 149 end 150 151 if aggregate.is_a?(Aggregate::Result::Base) 152 aggregate_report = aggregate.to_s 153 else 154 next 155 end 156 157 result.puts Util.colorize(:bold, "Summary of %s:" % display_as) 158 result.puts 159 unless aggregate_report == "" 160 result.puts aggregate.to_s.split("\n").map{|x| " " + x}.join("\n") 161 else 162 result.puts Util.colorize(:yellow, " No aggregate summary could be computed") 163 end 164 result.puts 165 end 166 167 @aggregate_failures.each do |failed| 168 case(failed[:type]) 169 when :startup 170 message = "exception raised while processing startup hook" 171 when :create 172 message = "unspecified output '#{failed[:name]}' for the action" 173 when :process_result 174 message = "exception raised while processing result data" 175 when :summarize 176 message = "exception raised while summarizing" 177 end 178 179 result.puts Util.colorize(:bold, "Summary of %s:" % failed[:name]) 180 result.puts 181 result.puts Util.colorize(:yellow, " Could not compute summary - %s" % message) 182 result.puts 183 end 184 185 result.string 186 end
helper to time block execution time
# File lib/mcollective/rpc/stats.rb 97 def time_block_execution(action) 98 if action == :start 99 @block_start = Time.now.to_f 100 elsif action == :end 101 @blocktime += Time.now.to_f - @block_start 102 else 103 raise("Uknown block action #{action}") 104 end 105 rescue 106 @blocktime = 0 107 end
Utility to time discovery from :start to :end
# File lib/mcollective/rpc/stats.rb 84 def time_discovery(action) 85 if action == :start 86 @discovery_start = Time.now.to_f 87 elsif action == :end 88 @discoverytime = Time.now.to_f - @discovery_start 89 else 90 raise("Uknown discovery action #{action}") 91 end 92 rescue 93 @discoverytime = 0 94 end
returns a hash of our stats
# File lib/mcollective/rpc/stats.rb 33 def to_hash 34 {:noresponsefrom => @noresponsefrom, 35 :unexpectedresponsefrom => @unexpectedresponsefrom, 36 :starttime => @starttime, 37 :discoverytime => @discoverytime, 38 :blocktime => @blocktime, 39 :responses => @responses, 40 :totaltime => @totaltime, 41 :discovered => @discovered, 42 :discovered_nodes => @discovered_nodes, 43 :okcount => @okcount, 44 :requestid => @requestid, 45 :failcount => @failcount, 46 :aggregate_summary => @aggregate_summary, 47 :aggregate_failures => @aggregate_failures} 48 end
Returns a blob of text indicating what nodes responded but weren't discovered
# File lib/mcollective/rpc/stats.rb 274 def unexpected_response_report 275 result_text = StringIO.new 276 277 if @unexpectedresponsefrom.size > 0 278 result_text.puts Util.colorize(:red, "Unexpected response from:") 279 result_text.puts 280 281 field_size = Util.field_size(@unexpectedresponsefrom, 30) 282 fields_num = Util.field_number(field_size) 283 format = " " + ( " %-#{field_size}s" * fields_num ) 284 285 @unexpectedresponsefrom.sort.in_groups_of(fields_num) do |c| 286 result_text.puts format % c 287 end 288 end 289 290 result_text.string 291 end