Class: RequestResponseStats::RedisRecord

Inherits:
Object
  • Object
show all
Defined in:
lib/request_response_stats/redis_record.rb

Constant Summary collapse

REDIS_RR_KEY_NAMESPACE =
"api_req_res"
PERMITTED_KEYS =
[
  :key_name,
  :server_name,
  :api_name,
  :api_verb,
  :api_controller,
  :api_action,
  :request_count,
  :min_time,
  :max_time,
  :avg_time,
  :start_time,
  :end_time,
  :error_count,
  :min_used_memory_MB,
  :max_used_memory_MB,
  :avg_used_memory_MB,
  :min_swap_memory_MB,
  :max_swap_memory_MB,
  :avg_swap_memory_MB,
  :avg_gc_stat_diff,
  :min_gc_stat_diff,
  :max_gc_stat_diff,
].map(&:to_s)
AT_MAX_TIME =
nil
AT_ERROR_COUNT =
nil
AT_MAX_SWAP_MEMORY_MB =
nil
ALERT_THRESHOLD =
{
  max_time: AT_MAX_TIME || 30,
  error_count: AT_ERROR_COUNT || 2,
  max_swap_memory_MB: AT_MAX_SWAP_MEMORY_MB || 200,
}.stringify_keys

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key, value = nil) ⇒ RedisRecord

Returns a new instance of RedisRecord.



213
214
215
216
# File 'lib/request_response_stats/redis_record.rb', line 213

def initialize(key, value=nil)
  @key = key
  @value = value
end

Instance Attribute Details

#keyObject

Returns the value of attribute key.



9
10
11
# File 'lib/request_response_stats/redis_record.rb', line 9

def key
  @key
end

#valueObject

Returns the value of attribute value.



9
10
11
# File 'lib/request_response_stats/redis_record.rb', line 9

def value
  @value
end

Class Method Details

.all_keys(opts = {}) ⇒ Object



69
70
71
72
73
74
75
76
77
78
# File 'lib/request_response_stats/redis_record.rb', line 69

def all_keys(opts={})
  support = opts[:support] || false
  if support
    regex = /^#{REDIS_RR_KEY_NAMESPACE}/
  else
    regex = /^#{REDIS_RR_KEY_NAMESPACE}_PUBLIC/
  end

  redis.keys.select{|k| k =~ regex}.sort.reverse
end

.del(key) ⇒ Object

delete value from redis



65
66
67
# File 'lib/request_response_stats/redis_record.rb', line 65

def del(key)
  redis.del(key)
end

.flush_all_keysObject



104
105
106
# File 'lib/request_response_stats/redis_record.rb', line 104

def flush_all_keys
  redis.del(*all_keys(support: true)) if all_keys.present?
end

.formatted_parsed_get_for_mongo(key) ⇒ Object

it returns parsed result into the format required for Mongo dump



86
87
88
89
90
91
92
# File 'lib/request_response_stats/redis_record.rb', line 86

def formatted_parsed_get_for_mongo(key)
  data = parsed_get(key)
  data["start_time"] = date_time_str_to_obj(data["start_time"])
  data["end_time"] = date_time_str_to_obj(data["end_time"])

  data
end

.freezed_keysObject



151
152
153
# File 'lib/request_response_stats/redis_record.rb', line 151

def freezed_keys
  all_keys.map{|k| self.new(k)}.select{|k| k.is_key_freezed?}.map{|rr| rr.key}
end

.get(key) ⇒ Object

get value from redis



55
56
57
# File 'lib/request_response_stats/redis_record.rb', line 55

def get(key)
  redis.get(key)
end

.get_slot_range_for_key(redis_key) ⇒ Object



124
125
126
127
128
# File 'lib/request_response_stats/redis_record.rb', line 124

def get_slot_range_for_key(redis_key)
  date_slot_string = redis_key.split("_")[-1]

  get_slot_range_for_date_slot_string(date_slot_string)
end

.group_stats_by_time_durationObject

Raises:

  • (StandardError)


108
109
110
# File 'lib/request_response_stats/redis_record.rb', line 108

def group_stats_by_time_duration
  raise StandardError, "UNDEFINED #{__method__}"
end

.hashify_all_data(opts = {}) ⇒ Object



94
95
96
97
98
99
100
101
102
# File 'lib/request_response_stats/redis_record.rb', line 94

def hashify_all_data(opts={})
  support = opts[:support] || false
  req_res_stat = ActiveSupport::HashWithIndifferentAccess.new
  all_keys(support: support).each do |key|
    req_res_stat[key] = ActiveSupport::HashWithIndifferentAccess.new(parsed_get key)
  end

  req_res_stat
end

.jsonified_set(key, value, options = {}, custom_options = {strict_key_check: true}) ⇒ Object

set jsonified value to redis and raise alerts



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/request_response_stats/redis_record.rb', line 131

def jsonified_set(key, value, options={}, custom_options={strict_key_check: true})
  value.select!{|k,v| PERMITTED_KEYS.include? k.to_s} if custom_options[:strict_key_check]

  # set jsonified value to redis
  redis.set(key, value.to_json, options)

  # get alerts collection
  alerts = ALERT_THRESHOLD.select{ |k, v| value[k] >= v if value[k] }.map{|k,v| {
    redis_key: key,
    alarm_key: k,
    alarm_value: v,
    actual_value: value[k]
  }}
  alerts_data = {data: alerts}.to_json
  raise_alert(alerts_data) if alerts.present?

  # return alerts
  alerts_data
end

.parsed_get(key) ⇒ Object

return parsed value from redis



81
82
83
# File 'lib/request_response_stats/redis_record.rb', line 81

def parsed_get(key)
  JSON.parse(redis.get(key) || "{}")
end

.query(params = {}) ⇒ Object

lets you fetch records for given conditions from redis



156
157
158
# File 'lib/request_response_stats/redis_record.rb', line 156

def query(params={})
  # to implement
end

.redisObject

it returns the redis connection this method must be redefined for ‘RedisRecord` to be useable

Raises:

  • (StandardError)


50
51
52
# File 'lib/request_response_stats/redis_record.rb', line 50

def redis
  raise StandardError, "UNDEFINED #{__method__}"
end

.req_key(server_name, req_object_id) ⇒ Object



116
117
118
# File 'lib/request_response_stats/redis_record.rb', line 116

def req_key(server_name, req_object_id)
  support_key(server_name, ["REQ_OBJ", req_object_id].join("_"))
end

.req_res_key(server_name, api_name, api_http_verb) ⇒ Object



120
121
122
# File 'lib/request_response_stats/redis_record.rb', line 120

def req_res_key(server_name, api_name, api_http_verb)
  ["#{REDIS_RR_KEY_NAMESPACE}_PUBLIC_#{server_name}_#{api_name}_#{api_http_verb}", get_time_slot_name].compact.join("_")
end

.set(key, value, options = {}) ⇒ Object

set value to redis



60
61
62
# File 'lib/request_response_stats/redis_record.rb', line 60

def set(key, value, options={})
  redis.set(key, value, options)
end

.support_key(server_name, key_name = "default") ⇒ Object



112
113
114
# File 'lib/request_response_stats/redis_record.rb', line 112

def support_key(server_name, key_name="default")
  [REDIS_RR_KEY_NAMESPACE, "SUPPORT", server_name.to_s, key_name].join("_")
end

Instance Method Details

#is_key_freezed?Boolean

if a key is freezed then no more data will be written to it

Returns:

  • (Boolean)


219
220
221
222
223
# File 'lib/request_response_stats/redis_record.rb', line 219

def is_key_freezed?
  return nil unless self.class.group_stats_by_time_duration

  self.class.get_slot_range_for_key(key)[1] < Time.now
end