class RequestResponseStats::ReqResStat
Constants
- DEFAULT_STATS_GRANULARITY
- PERCISION
Public Class Methods
wrapper around `get_stat` for :avg stat for more info, check documentation for `get_stat`
# File lib/request_response_stats/req_res_stat.rb, line 88 def get_avg(key, start_time, end_time, granularity = DEFAULT_STATS_GRANULARITY) data = get_stat("sum", key, start_time, end_time, granularity) data.each do |e| e[:stat_type] = "avg" if e[:count] != 0 e[:data] = (e[:data] * 1.0 / e[:count]).try(:round, PERCISION) else e[:data] = 0 end end data end
instead of aggregated values (such as in `get_stat`), it returns grouped values for given key, given granularity level, and given start_time and end_time set `stat_type` as `nil` to return grouped but uncompacted data otherwise, you can set `stat_type` as :sum, :max, :min, :avg to get grouped data TODO: Ignore `start_time` and `end_time` if a time-based collection is passed TODO: Optimize `get_time_ranges` to not to calculate time_ranges again and again for same `start_time` and `end_time` (that is, for same time-based collection
# File lib/request_response_stats/req_res_stat.rb, line 109 def get_details(key, start_time, end_time, stat_type = nil, granularity = DEFAULT_STATS_GRANULARITY) # get ungrouped data stat_type = stat_type.to_s.to_sym if stat_type key = key.to_s.to_sym relevant_records = get_within(start_time, end_time) time_ranges = get_time_ranges(start_time, end_time, granularity) stats = time_ranges.map do |time_range| data_for_time_range = relevant_records.get_within(*time_range.values).map{ |r| {server_plus_api: r.server_plus_api, data: r[key], key_name: r.key_name} } {data: data_for_time_range, **time_range} end # grouping data by :server_plus_api stats.each do |r| data = r[:data] data = data.map{ |e| {server_plus_api: e[:server_plus_api], data: e[:data]} } data = data.group_by { |e| e[:server_plus_api] } r[:data] = data end # calculating grouped value based on stat_type if stat_type if [:sum, :min, :max].include? stat_type # calculate grouped value stats.each do |r| data = r[:data] data = data.map do |k, v| # {server_plus_api: k, data: v.map{|e| e[:data]}} element_data = v.map{|e| e[:data]} {server_plus_api: k, count: element_data.size, data: element_data.compact.public_send(stat_type).try(:round, PERCISION)} end r[:data] = data end stats elsif stat_type == :avg data = get_details(key, start_time, end_time, stat_type = :sum, granularity) data.each do |r| r[:data].each do |e| e[:data] = (e[:data] * 1.0 / e[:count]).try(:round, PERCISION) end end data else "This :stat_type is not supported" end else stats end end
wrapper around `get_stat` for :max stat for more info, check documentation for `get_stat`
# File lib/request_response_stats/req_res_stat.rb, line 82 def get_max(key, start_time, end_time, granularity = DEFAULT_STATS_GRANULARITY) get_stat("max", key, start_time, end_time, granularity) end
wrapper around `get_stat` for :min stat for more info, check documentation for `get_stat`
# File lib/request_response_stats/req_res_stat.rb, line 76 def get_min(key, start_time, end_time, granularity = DEFAULT_STATS_GRANULARITY) get_stat("min", key, start_time, end_time, granularity) end
wrapper around `get_stat` for :sum stat for more info, check documentation for `get_stat`
# File lib/request_response_stats/req_res_stat.rb, line 70 def get_sum(key, start_time, end_time, granularity = DEFAULT_STATS_GRANULARITY) get_stat("sum", key, start_time, end_time, granularity) end
Note: `start_time` and `end_time` are Time objects `start_time` in inclusive but `end_time` is not Use `get_within` with `nil` values for `start_time` and `end_time` to minimize database hits for same kind of queries on same date-range of data
# File lib/request_response_stats/req_res_stat.rb, line 60 def get_within(start_time, end_time) if start_time || end_time where(:start_time.gte => start_time, :end_time.lt => end_time) else all end end
Private Class Methods
it returns aggreated values for given key for given granularity in between given start_time and end_time stat: [“sum”, “min”, “max”] Note that [].sum is 0, whereas, [].min and [].max is nil
# File lib/request_response_stats/req_res_stat.rb, line 182 def get_stat(stat_type, key, start_time, end_time, granularity = DEFAULT_STATS_GRANULARITY) stat_type = stat_type.to_s.to_sym key = key.to_s.to_sym relevant_records = get_within(start_time, end_time) time_ranges = get_time_ranges(start_time, end_time, granularity) stats = time_ranges.map do |time_range| time_range_data = relevant_records.get_within(*time_range.values).pluck(key) data = time_range_data.compact.public_send(stat_type).try(:round, PERCISION) {key: key, stat_type: stat_type, data: data, count: time_range_data.size, **time_range} end stats end
# File lib/request_response_stats/req_res_stat.rb, line 165 def get_time_ranges(start_time, end_time, granularity = DEFAULT_STATS_GRANULARITY) slots = (((end_time - start_time) / granularity).ceil) rescue 0 current_start_time = start_time time_ranges = (1..slots).map do |slot| value = {start_time: current_start_time, end_time: current_start_time + granularity} current_start_time += granularity value end time_ranges[-1][:end_time] = end_time if time_ranges[-1] && (time_ranges[-1][:end_time] > end_time) time_ranges end
Public Instance Methods
returns a string identifying server_name, api_name, and api_verb
# File lib/request_response_stats/req_res_stat.rb, line 50 def server_plus_api [server_name, api_name, api_verb].join("_") end