-
Notifications
You must be signed in to change notification settings - Fork 7
/
stats_by_user.rb
98 lines (86 loc) · 2.79 KB
/
stats_by_user.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# This script will pull Ping Thing data through the valdiators.app API and show
# stats by user. It will also write a CSV file.
#
# Gems:
# gem install csv
# gem install dotenv
# gem install json
# gem install validators_app_ruby
#
# Usage:
# ruby stats_by_user.rb [limit (integer, default 1000)]
require 'csv'
require 'dotenv'
require 'json'
require 'validators_app_ruby'
Dotenv.load
limit = ARGV[0] || 1000
csv_file = 'stats_by_user.csv'
va = ValidatorsAppRuby.new(token: ENV['VA_API_KEY'])
rows = va.get_ping_thing(network: "mainnet", limit: limit)
puts "#{rows.count} rows"
# Add a couple of helper methods
module StatsLogic
def array_average(array)
return nil unless array.is_a? Array
return nil if array.empty?
return nil if array.sum.nil?
array.sum.to_i / array.size.to_f
end
def array_median(array)
return nil unless array.is_a? Array
return nil if array.empty?
sorted = array.sort
mid = (sorted.length - 1) / 2.0
(sorted[mid.floor] + sorted[mid.ceil]) / 2.0
end
end
include StatsLogic
# Accumulate data for the statistical calculations
stats = {}
rows.each do |row|
stats[row['username']] = {
confirmation_times: [],
slot_latencies: []
} if stats[row['username']].nil?
stats[row['username']][:slot_latencies] << (row['slot_landed'].to_i - row['slot_sent'].to_i)
stats[row['username']][:confirmation_times] << row['response_time']
end
ltcy_width = 16
conf_width = 13
output_fields = [
'user name'.ljust(20, ' '),
'count'.rjust(6, ' '),
'avg slot ltncy'.rjust(ltcy_width, ' '),
'med slot ltncy'.rjust(ltcy_width, ' '),
'avg conf ms'.rjust(conf_width, ' '),
'med conf ms'.rjust(conf_width, ' ')
]
puts ''
puts "#{output_fields.join('')}"
# Open a CSV file for writing
CSV.open(csv_file, 'wb') do |csv|
csv << output_fields.map{ |f| f.strip }
stats.sort.each do |k,v|
row_count = v[:slot_latencies].length.to_s.rjust(6, ' ')
slot_latency_avg = (v[:slot_latencies].sum/v[:slot_latencies].length.to_f)
.round(1)
.to_s
.rjust(ltcy_width, ' ')
slot_latency_med = array_median(v[:slot_latencies])
.to_s
.rjust(ltcy_width, ' ')
avg_conf_time = (v[:confirmation_times].sum/v[:confirmation_times].length)
.to_s
.rjust(conf_width, ' ')
conf_time_med = array_median(v[:confirmation_times])
.to_i
.to_s
.rjust(conf_width, ' ')
csv << [k, row_count, slot_latency_avg,slot_latency_med,avg_conf_time,conf_time_med].map{|f| f.strip}
puts "#{k.ljust(20, ' ')}#{row_count}#{slot_latency_avg}#{slot_latency_med}#{avg_conf_time}#{conf_time_med}"
end
end
puts ''
puts "CSV file written to '#{csv_file}'"
puts ''