Class: Check::Metric
- Inherits:
-
Hashr
- Object
- Hashr
- Check::Metric
- Defined in:
- lib/check/metric.rb
Class Method Summary collapse
-
.defaults ⇒ Object
If you really want to overwrite the defaults completely, inherit this class and re-define self.defaults.
-
.defaults=(params = {}) ⇒ Object
In this example, we are overwriting the defaults so that all new configs will consider 5 matches over a period of 60 seconds to be a positive.
- .delete_all(name) ⇒ Object
- .find(params = {}) ⇒ Object
Instance Method Summary collapse
- #check(params) ⇒ Object
- #delete ⇒ Object
- #delete_associated ⇒ Object
- #delete_matches ⇒ Object (also: #clear_matches)
- #delete_positives ⇒ Object (also: #clear_positives)
- #disable ⇒ Object
- #disable! ⇒ Object
- #disable_key ⇒ Object
- #disabled? ⇒ Boolean
- #enable! ⇒ Object (also: #delete_disable)
- #errors ⇒ Object
- #id ⇒ Object
- #matches ⇒ Object
- #matches_key ⇒ Object
- #namespace(string) ⇒ Object
- #notify(message) ⇒ Object
- #notify? ⇒ Boolean
- #pack ⇒ Object (also: #packed)
- #persisted? ⇒ Boolean
- #positives ⇒ Object
- #positives_key ⇒ Object
- #save ⇒ Object
- #set ⇒ Object
- #similar ⇒ Object
- #suspended?(timestamp = Time.now.utc.to_i) ⇒ Boolean
- #trigger_positive? ⇒ Boolean
- #unpack(value) ⇒ Object
- #valid? ⇒ Boolean
- #valid_name? ⇒ Boolean
Class Method Details
.defaults ⇒ Object
If you really want to overwrite the defaults completely, inherit this class and re-define self.defaults. Don’t forget to invoke the define method with the new defaults as this is Hashr’s way of defining the hash blueprint.
It would be interesting to go further with positives and categorize them as consistent (>50% matches are lower or higher) or fluctuating (50/50).
19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/check/metric.rb', line 19 def self.defaults { lower: 1, upper: 10, matches_for_positive: 2, over_seconds: 60, suspend_after_positives: 1, keep_positives: 10, suspend_for_seconds: 1800 } end |
.defaults=(params = {}) ⇒ Object
In this example, we are overwriting the defaults so that all new configs will consider 5 matches over a period of 60 seconds to be a positive. The metric check will be suspended for 1h after 3 positives. The lower and upper bounds are also adjusted.
Check::Metric.defaults = {
lower: 10,
upper: 100,
matches_for_positive: 5,
over_seconds: 60,
suspend_after_positives: 3,
suspend_for_seconds: 3600
}
46 47 48 |
# File 'lib/check/metric.rb', line 46 def self.defaults=(params={}) define self.defaults.merge(params) end |
.delete_all(name) ⇒ Object
50 51 52 |
# File 'lib/check/metric.rb', line 50 def self.delete_all(name) Redis.current.del(name) end |
.find(params = {}) ⇒ Object
54 55 56 |
# File 'lib/check/metric.rb', line 54 def self.find(params={}) Metric.new(params) end |
Instance Method Details
#check(params) ⇒ Object
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/check/metric.rb', line 176 def check(params) = params.fetch(:timestamp) { Time.now.utc }.to_i value = params.fetch(:value) similar.each do |metric| next if metric.suspended?() or metric.disabled? unless value.between?(metric.fetch(:lower), metric.fetch(:upper)) metric.matches.push({ value: value, timestamp: }) end if metric.trigger_positive? new_positive = { timestamp: metric.matches.last.fetch(:timestamp), matches: metric.matches.values } metric.positives.push(new_positive) notify(new_positive.merge(metric)) metric.clear_matches end end end |
#delete ⇒ Object
82 83 84 85 |
# File 'lib/check/metric.rb', line 82 def delete delete_associated set.delete(packed) end |
#delete_associated ⇒ Object
127 128 129 |
# File 'lib/check/metric.rb', line 127 def delete_associated Redis.current.del([matches_key, positives_key, disable_key]) end |
#delete_matches ⇒ Object Also known as: clear_matches
111 112 113 |
# File 'lib/check/metric.rb', line 111 def delete_matches Redis.current.del(matches_key) end |
#delete_positives ⇒ Object Also known as: clear_positives
121 122 123 |
# File 'lib/check/metric.rb', line 121 def delete_positives Redis.current.del(positives_key) end |
#disable ⇒ Object
141 142 143 |
# File 'lib/check/metric.rb', line 141 def disable Redis::Value.new(disable_key, marshal: true) end |
#disable! ⇒ Object
145 146 147 |
# File 'lib/check/metric.rb', line 145 def disable! disable.value = true end |
#disable_key ⇒ Object
103 104 105 |
# File 'lib/check/metric.rb', line 103 def disable_key namespace("disable") end |
#disabled? ⇒ Boolean
154 155 156 |
# File 'lib/check/metric.rb', line 154 def disabled? disable.exists? end |
#enable! ⇒ Object Also known as: delete_disable
149 150 151 |
# File 'lib/check/metric.rb', line 149 def enable! disable.delete end |
#errors ⇒ Object
202 203 204 205 |
# File 'lib/check/metric.rb', line 202 def errors return @errors if @errors @errors = {} end |
#id ⇒ Object
87 88 89 |
# File 'lib/check/metric.rb', line 87 def id hash.abs end |
#matches ⇒ Object
107 108 109 |
# File 'lib/check/metric.rb', line 107 def matches Redis::List.new(matches_key, maxlength: self.fetch(:matches_for_positive), marshal: true) end |
#matches_key ⇒ Object
95 96 97 |
# File 'lib/check/metric.rb', line 95 def matches_key namespace("matches") end |
#namespace(string) ⇒ Object
91 92 93 |
# File 'lib/check/metric.rb', line 91 def namespace(string) "#{self.fetch(:name)}:#{string}:#{self.id}" end |
#notify(message) ⇒ Object
172 173 174 |
# File 'lib/check/metric.rb', line 172 def notify() Redis.current.publish(REDIS_NOTIFICATIONS, .to_msgpack) if notify? end |
#notify? ⇒ Boolean
168 169 170 |
# File 'lib/check/metric.rb', line 168 def notify? REDIS_NOTIFICATIONS.strip != "" end |
#pack ⇒ Object Also known as: packed
68 69 70 |
# File 'lib/check/metric.rb', line 68 def pack self.to_hash.to_msgpack end |
#persisted? ⇒ Boolean
221 222 223 |
# File 'lib/check/metric.rb', line 221 def persisted? set.include?(packed) end |
#positives ⇒ Object
117 118 119 |
# File 'lib/check/metric.rb', line 117 def positives Redis::List.new(positives_key, maxlength: self.fetch(:keep_positives), marshal: true) end |
#positives_key ⇒ Object
99 100 101 |
# File 'lib/check/metric.rb', line 99 def positives_key namespace("positives") end |
#save ⇒ Object
77 78 79 80 |
# File 'lib/check/metric.rb', line 77 def save set.add(packed) if valid? self end |
#set ⇒ Object
58 59 60 |
# File 'lib/check/metric.rb', line 58 def set Redis::Set.new(self.fetch(:name)) if valid_name? end |
#similar ⇒ Object
62 63 64 65 66 |
# File 'lib/check/metric.rb', line 62 def similar set.members.map do |member| Metric.new(unpack(member)) end end |
#suspended?(timestamp = Time.now.utc.to_i) ⇒ Boolean
131 132 133 134 135 136 137 138 139 |
# File 'lib/check/metric.rb', line 131 def suspended?(=Time.now.utc.to_i) last_positive = positives.last if last_positive - last_positive.fetch(:timestamp) <= self.fetch(:suspend_for_seconds) else false end end |
#trigger_positive? ⇒ Boolean
158 159 160 161 162 163 164 165 166 |
# File 'lib/check/metric.rb', line 158 def trigger_positive? first_match = matches.first last_match = matches.last if first_match and last_match matches.length == self.fetch(:matches_for_positive) and last_match.fetch(:timestamp) - first_match.fetch(:timestamp) <= self.fetch(:over_seconds) end end |
#unpack(value) ⇒ Object
73 74 75 |
# File 'lib/check/metric.rb', line 73 def unpack(value) MessagePack.unpack(value) end |
#valid? ⇒ Boolean
217 218 219 |
# File 'lib/check/metric.rb', line 217 def valid? valid_name? end |
#valid_name? ⇒ Boolean
207 208 209 210 211 212 213 214 215 |
# File 'lib/check/metric.rb', line 207 def valid_name? if (self.fetch(:name) { "" }.strip != "") errors.delete(:name) return true else errors[:name] = "can't be blank" return false end end |