5 # directory to hold conditions and their corresponding metric
6 # {condition => metric}
7 attr_accessor :directory
12 def self.attach(condition, metric)
13 self.directory[condition] = metric
17 Timer.get.schedule(condition, 0)
18 when EventCondition, TriggerCondition
23 def self.detach(condition)
24 self.directory.delete(condition)
28 Timer.get.unschedule(condition)
29 when EventCondition, TriggerCondition
34 def self.trigger(condition)
37 self.handle_poll(condition)
38 when EventCondition, TriggerCondition
39 self.handle_event(condition)
43 def self.handle_poll(condition)
46 metric = self.directory[condition]
48 # it's possible that the timer will trigger an event before it can be cleared
49 # by an exiting metric, in which case it should be ignored
53 watch.mutex.synchronize do
55 result = condition.test
58 self.log(watch, metric, condition, result)
62 self.notify(condition, msg)
70 if result && condition.transition
75 metric.destination && metric.destination[result]
78 # transition or reschedule
83 rescue EventRegistrationFailedError
84 msg = watch.name + ' Event registration failed, moving back to previous state'
86 LOG.log(watch, :info, msg)
93 Timer.get.schedule(condition)
98 message = format("Unhandled exception (%s): %s\n%s",
99 e.class, e.message, e.backtrace.join("\n"))
106 def self.handle_event(condition)
108 metric = self.directory[condition]
113 watch.mutex.synchronize do
115 self.log(watch, metric, condition, true)
119 self.notify(condition, msg)
122 # get the destination
124 if condition.transition
129 metric.destination && metric.destination[true]
142 def self.log(watch, metric, condition, result)
143 # log info if available
147 if (metric.destination && metric.destination.keys.size == 2) || result == true
153 Array(condition.info).each do |condition_info|
154 msg = "#{watch.name} #{status} #{condition_info} (#{condition.base_name})"
156 LOG.log(watch, :info, msg % [])
158 rescue Exception => e
160 puts e.backtrace.join("\n")
163 msg = "#{watch.name} [unknown] (#{condition.base_name})"
165 LOG.log(watch, :info, msg % [])
169 msg = watch.name + ' ' + condition.base_name + " [#{result}] " + self.dest_desc(metric, condition)
171 LOG.log(watch, :debug, msg)
174 def self.dest_desc(metric, condition)
175 if condition.transition
176 {true => condition.transition}.inspect
178 if metric.destination
179 metric.destination.inspect
186 def self.notify(condition, message)
188 spec = Contact.normalize(condition.notify)
192 spec[:contacts].inject([]) do |acc, contact_name_or_group|
193 acc += Array(God.contacts[contact_name_or_group] || God.contact_groups[contact_name_or_group])
199 resolved_contacts.each do |c|
200 c.notify(message, Time.now, spec[:priority], spec[:category])
204 puts e.backtrace.join("\n")