4 class Flapping < TriggerCondition
5 attr_accessor :times, :within, :from_state, :to_state, :retry_in, :retry_times, :retry_within
8 @timeline = Timeline.new(self.times)
9 @retry_timeline = Timeline.new(self.retry_times)
14 valid &= complain("You must specify the 'times' attribute for :flapping") if self.times.nil?
15 valid &= complain("You must specify the 'within' attribute for :flapping") if self.within.nil?
16 valid &= complain("You must specify either the 'from_state', 'to_state', or both attributes for :flapping") if self.from_state.nil? && self.to_state.nil?
20 def process(event, payload)
22 if event == :state_change
23 event_from_state, event_to_state = *payload
25 from_state_match = !self.from_state || self.from_state && Array(self.from_state).include?(event_from_state)
26 to_state_match = !self.to_state || self.to_state && Array(self.to_state).include?(event_to_state)
28 if from_state_match && to_state_match
31 concensus = (@timeline.size == self.times)
32 duration = (@timeline.last - @timeline.first) < self.within
34 if concensus && duration
42 puts e.backtrace.join("\n")
50 @retry_timeline << Time.now
52 concensus = (@retry_timeline.size == self.retry_times)
53 duration = (@retry_timeline.last - @retry_timeline.first) < self.retry_within
55 if concensus && duration
61 msg = "#{self.watch.name} giving up"
63 LOG.log(self.watch, :info, msg)
71 msg = "#{self.watch.name} auto-reenable monitoring in #{self.retry_in} seconds"
73 LOG.log(self.watch, :info, msg)
78 msg = "#{self.watch.name} auto-reenabling monitoring"
80 LOG.log(self.watch, :info, msg)
82 if self.watch.state == :unmonitored