Class: DRbDump::Statistics

Inherits:
Object
  • Object
show all
Defined in:
lib/drbdump/statistics.rb

Overview

Collects and displays statistics on captured packets.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeStatistics

:nodoc:



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/drbdump/statistics.rb', line 68

def initialize # :nodoc:
  @drb_exceptions_raised = 0
  @drb_results_received  = 0
  @drb_messages_sent     = 0
  @drb_packet_count      = 0
  @rinda_packet_count    = 0
  @total_packet_count    = 0

  # [message][argc]
  @message_allocations = two_level_statistic_hash
  @message_latencies   = two_level_statistic_hash

  # [source][destination]
  @peer_latencies = two_level_statistic_hash

  @last_peer_send = Hash.new do |sources, source|
    sources[source] = Hash.new
  end

  @last_sent_message = Hash.new do |sources, source|
    sources[source] = Hash.new
  end
end

Instance Attribute Details

#drb_exceptions_raisedObject

Number of DRb exceptions raised



9
10
11
# File 'lib/drbdump/statistics.rb', line 9

def drb_exceptions_raised
  @drb_exceptions_raised
end

#drb_messages_sentObject

Number of DRb messages sent



19
20
21
# File 'lib/drbdump/statistics.rb', line 19

def drb_messages_sent
  @drb_messages_sent
end

#drb_packet_countObject

Number of DRb packets seen



24
25
26
# File 'lib/drbdump/statistics.rb', line 24

def drb_packet_count
  @drb_packet_count
end

#drb_results_receivedObject

Number of DRb results received



14
15
16
# File 'lib/drbdump/statistics.rb', line 14

def drb_results_received
  @drb_results_received
end

#last_peer_sendObject

Records the last timestamp for a message sent between peers



29
30
31
# File 'lib/drbdump/statistics.rb', line 29

def last_peer_send
  @last_peer_send
end

#last_sent_messageObject

Records the last message sent between peers



34
35
36
# File 'lib/drbdump/statistics.rb', line 34

def last_sent_message
  @last_sent_message
end

#message_allocationsObject

Records statistics about allocations required to send a message. The outer key is the message name while the inner key is the argument count (including block).



41
42
43
# File 'lib/drbdump/statistics.rb', line 41

def message_allocations
  @message_allocations
end

#message_latenciesObject

Records statistics about latencies for sent messages. The outer key is the message name while the inner key is the argument count (including block).

The recorded latency is from the first packet in the message-send to the last packet in the message result.



51
52
53
# File 'lib/drbdump/statistics.rb', line 51

def message_latencies
  @message_latencies
end

#peer_latenciesObject

Records statistics about latencies for messages sent between peers



56
57
58
# File 'lib/drbdump/statistics.rb', line 56

def peer_latencies
  @peer_latencies
end

#rinda_packet_countObject

Number of Rinda packets seen



61
62
63
# File 'lib/drbdump/statistics.rb', line 61

def rinda_packet_count
  @rinda_packet_count
end

#total_packet_countObject

Number of packets seen, including non-DRb traffic



66
67
68
# File 'lib/drbdump/statistics.rb', line 66

def total_packet_count
  @total_packet_count
end

Instance Method Details

#add_message_send(message) ⇒ Object

Adds information from message



95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/drbdump/statistics.rb', line 95

def add_message_send message
  @drb_messages_sent += 1

  msg  = message.message
  argc = message.argument_count

  source      = message.source
  destination = message.destination

  @last_peer_send[source][destination] = message.timestamp
  @last_sent_message[source][destination] = msg, argc, message.allocations
end

#add_result(result) ⇒ Object

Adds information from result



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/drbdump/statistics.rb', line 111

def add_result result
  source      = result.source
  destination = result.destination

  @drb_results_received += 1
  @drb_exceptions_raised += 1 unless result.status

  sent_timestamp = @last_peer_send[destination].delete source
  message, argc, allocations = @last_sent_message[destination].delete source

  return unless sent_timestamp

  latency = result.timestamp - sent_timestamp

  @peer_latencies[destination][source].add latency
  @message_latencies[message][argc].add latency
  @message_allocations[message][argc].add allocations + result.allocations
end

#adjust_units(stats, unit) ⇒ Object

Adjusts units in stats from unit to milli-unit if the minimum value is below the required threshold



134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/drbdump/statistics.rb', line 134

def adjust_units stats, unit # :nodoc:
  if stats.first > 0.05 then
    stats << unit
    return stats
  end

  unit.replace "m#{unit}"

  stats = stats.map { |stat| stat * 1000 }

  stats << unit
end

#extract_and_size(data) ⇒ Object

Extracts data and column widths from data



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/drbdump/statistics.rb', line 150

def extract_and_size data # :nodoc:
  max_outer_size = 0
  max_inner_size = 0
  max_count      = 0

  rows = []

  data.each do |outer_key, inner|
    max_outer_size = [max_outer_size, outer_key.to_s.size].max

    inner.each do |inner_key, stat|
      count, *rest = stat.to_a

      rows << [outer_key, inner_key, count, *rest]

      max_inner_size = [max_inner_size, inner_key.to_s.size].max
      max_count      = [max_count, count].max
    end
  end

  max_count_size = max_count.to_s.size

  return max_outer_size, max_inner_size, max_count_size, rows
end

#merge_results(allocation_rows, latency_rows) ⇒ Object

Merges allocation_rows and latency_rows into a single data set.



178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/drbdump/statistics.rb', line 178

def merge_results allocation_rows, latency_rows # :nodoc:
  allocations = allocation_rows.group_by { |message, argc,| [message, argc] }
  latencies   = latency_rows.group_by { |message, argc,| [message, argc] }

  allocations.map do |group, (row, _)|
    latency_row, = latencies.delete(group)

    if latency_row then
      row.concat latency_row.last 4
    else
      row.concat [0, 0, 0, 0]
    end
  end
end

#multiple_peers(count_size, source_size, destination_size, rows) ⇒ Object

Collapses multiple single-message peers in rows to a single row.



196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/drbdump/statistics.rb', line 196

def multiple_peers count_size, source_size, destination_size, rows # :nodoc:
  rows = rows.sort_by { |_, _, count| -count }

  rows.map do |source, destination, count, *stats|
    stats = adjust_units stats, 's'

    '%2$*1$d messages: %4$*3$s to %6$*5$s; ' % [
      count_size, count, source_size, source, destination_size, destination
    ] +
    '%0.3f, %0.3f, %0.3f, %0.3f %s' % stats
  end
end

#per_message_resultsObject

:nodoc:



209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/drbdump/statistics.rb', line 209

def per_message_results # :nodoc:
  name_size, argc_size, sends_size, allocation_rows =
    extract_and_size @message_allocations

  _, _, _, latency_rows = extract_and_size @message_latencies

  rows = merge_results allocation_rows, latency_rows

  rows = rows.sort_by { |message, argc, count,| [-count, message, argc] }

  return name_size, argc_size, sends_size, rows
end

#showObject

Writes all statistics on packets and messages processesed to $stdout



237
238
239
240
241
242
243
# File 'lib/drbdump/statistics.rb', line 237

def show
  show_basic
  puts
  show_messages
  puts
  show_peers
end

#show_basicObject

Writes basic statistics on packets and messages processed to $stdout



248
249
250
251
252
253
254
255
# File 'lib/drbdump/statistics.rb', line 248

def show_basic
  puts "#{@total_packet_count} total packets captured"
  puts "#{@rinda_packet_count} Rinda packets captured"
  puts "#{@drb_packet_count} DRb packets captured"
  puts "#{@drb_messages_sent} messages sent"
  puts "#{@drb_results_received} results received"
  puts "#{@drb_exceptions_raised} exceptions raised"
end

#show_messagesObject

Shows message-send statistics including arguments per calls, count of calls and average and standard deviation of allocations.



279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/drbdump/statistics.rb', line 279

def show_messages # :nodoc:
  name_size, argc_size, sends_size, rows = per_message_results

  output = rows.map do |message, argc, count, *stats|
    allocation_stats = stats.first 4
    latency_stats   = adjust_units stats.last(4), 's'

    '%-2$*1$s (%4$*3$s args) %6$*5$d sent; ' % [
        name_size, message, argc_size, argc, sends_size, count,
    ] +
    '%0.1f, %0.1f, %0.1f, %0.1f allocations; ' % allocation_stats +
    '%0.3f, %0.3f, %0.3f, %0.3f %s' % latency_stats
  end

  puts 'Messages sent min, avg, max, stddev:'
  puts output
end

#show_peersObject

Shows peer statistics



260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/drbdump/statistics.rb', line 260

def show_peers
  source_size, destination_size, count_size, rows =
    extract_and_size @peer_latencies

  multiple, single = rows.partition { |_, _, count| count > 1 }

  multiple << single.pop if single.length == 1

  count_size = [count_size, single.length.to_s.size].max

  puts 'Peers min, avg, max, stddev:'
  puts multiple_peers count_size, source_size, destination_size, multiple
  puts single_peers count_size, single unless single.empty?
end

#single_peers(count_size, rows) ⇒ Object

Displays single peers



300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/drbdump/statistics.rb', line 300

def single_peers count_size, rows # :nodoc:
  return if rows.empty?

  statistic = DRbDump::Statistic.new

  rows.each do |_, _, _, value|
    statistic.add value
  end

  count, *stats = statistic.to_a

  stats = adjust_units stats, 's'

  '%2$*1$d single-message peers ' % [count_size, count] +
  '%0.3f, %0.3f, %0.3f, %0.3f %s' % stats
end

#two_level_statistic_hashObject

Creates a two-level statistic hash with a DRbDump::Statistic as the inner object for the keys.



226
227
228
229
230
231
232
# File 'lib/drbdump/statistics.rb', line 226

def two_level_statistic_hash # :nodoc:
  Hash.new do |outer, outer_key|
    outer[outer_key] = Hash.new do |inner, inner_key|
      inner[inner_key] = DRbDump::Statistic.new
    end
  end
end