flapjack 0.7.18 → 0.7.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +7 -0
- data/bin/flapjack +3 -0
- data/bin/flapjack-nagios-receiver +4 -1
- data/bin/flapjack-netsaint-parser +2 -1
- data/bin/flapjack-populator +6 -3
- data/bin/receive-events +3 -1
- data/bin/simulate-failed-check +2 -1
- data/etc/flapjack_config.yaml.example +20 -0
- data/features/events.feature +1 -1
- data/features/events_check_names.feature +1 -1
- data/features/notification_rules.feature +1 -1
- data/features/notifications.feature +1 -1
- data/features/steps/events_steps.rb +18 -17
- data/features/steps/flapjack-netsaint-parser_steps.rb +1 -2
- data/features/steps/notifications_steps.rb +14 -1
- data/features/support/env.rb +27 -10
- data/flapjack.gemspec +1 -3
- data/lib/flapjack/coordinator.rb +30 -20
- data/lib/flapjack/data/contact.rb +3 -2
- data/lib/flapjack/data/entity.rb +3 -3
- data/lib/flapjack/data/entity_check.rb +116 -43
- data/lib/flapjack/data/event.rb +10 -10
- data/lib/flapjack/data/message.rb +3 -6
- data/lib/flapjack/data/notification.rb +122 -57
- data/lib/flapjack/data/notification_rule.rb +11 -11
- data/lib/flapjack/filters/acknowledgement.rb +2 -2
- data/lib/flapjack/filters/ok.rb +1 -1
- data/lib/flapjack/gateways/api/entity_check_presenter.rb +1 -0
- data/lib/flapjack/gateways/api/entity_methods.rb +4 -6
- data/lib/flapjack/gateways/api/rack/json_params_parser.rb +1 -1
- data/lib/flapjack/gateways/email.rb +3 -5
- data/lib/flapjack/gateways/email/{alert.html.haml → alert.html.erb} +0 -0
- data/lib/flapjack/gateways/jabber.rb +66 -35
- data/lib/flapjack/gateways/oobetet.rb +5 -7
- data/lib/flapjack/gateways/pagerduty.rb +7 -7
- data/lib/flapjack/gateways/web.rb +101 -41
- data/lib/flapjack/gateways/web/public/css/flapjack.css +1 -1
- data/lib/flapjack/gateways/web/views/{_css.haml → _css.html.erb} +2 -1
- data/lib/flapjack/gateways/web/views/_foot.html.erb +3 -0
- data/lib/flapjack/gateways/web/views/_head.html.erb +4 -0
- data/lib/flapjack/gateways/web/views/_nav.html.erb +9 -0
- data/lib/flapjack/gateways/web/views/check.html.erb +204 -0
- data/lib/flapjack/gateways/web/views/checks.html.erb +77 -0
- data/lib/flapjack/gateways/web/views/contact.html.erb +114 -0
- data/lib/flapjack/gateways/web/views/contacts.html.erb +42 -0
- data/lib/flapjack/gateways/web/views/entities.html.erb +39 -0
- data/lib/flapjack/gateways/web/views/entity.html.erb +67 -0
- data/lib/flapjack/gateways/web/views/index.html.erb +27 -0
- data/lib/flapjack/gateways/web/views/self_stats.html.erb +97 -0
- data/lib/flapjack/logger.rb +71 -23
- data/lib/flapjack/notifier.rb +157 -0
- data/lib/flapjack/patches.rb +1 -41
- data/lib/flapjack/pikelet.rb +4 -2
- data/lib/flapjack/{executive.rb → processor.rb} +32 -145
- data/lib/flapjack/version.rb +1 -1
- data/spec/lib/flapjack/coordinator_spec.rb +134 -71
- data/spec/lib/flapjack/data/contact_spec.rb +1 -0
- data/spec/lib/flapjack/data/entity_check_spec.rb +146 -30
- data/spec/lib/flapjack/data/entity_spec.rb +4 -4
- data/spec/lib/flapjack/data/event_spec.rb +4 -4
- data/spec/lib/flapjack/data/message_spec.rb +2 -3
- data/spec/lib/flapjack/data/notification_spec.rb +13 -19
- data/spec/lib/flapjack/gateways/api/entity_methods_spec.rb +2 -2
- data/spec/lib/flapjack/gateways/jabber_spec.rb +34 -0
- data/spec/lib/flapjack/gateways/pagerduty_spec.rb +0 -2
- data/spec/lib/flapjack/gateways/web/views/{check.haml_spec.rb → check.html.erb_spec.rb} +2 -2
- data/spec/lib/flapjack/gateways/web/views/{contact.haml_spec.rb → contact.html.erb_spec.rb} +3 -3
- data/spec/lib/flapjack/gateways/web/views/index.html.erb_spec.rb +14 -0
- data/spec/lib/flapjack/gateways/web_spec.rb +20 -8
- data/spec/lib/flapjack/logger_spec.rb +30 -28
- data/spec/lib/flapjack/notifier_spec.rb +6 -0
- data/spec/lib/flapjack/pikelet_spec.rb +8 -8
- data/spec/lib/flapjack/{executive_spec.rb → processor_spec.rb} +4 -4
- data/spec/spec_helper.rb +1 -13
- data/spec/support/erb_view_helper.rb +23 -0
- data/tasks/profile.rake +1 -1
- data/tmp/acknowledge.rb +3 -1
- data/tmp/create_event_ok.rb +3 -1
- data/tmp/create_event_unknown.rb +3 -1
- data/tmp/create_events_failure.rb +3 -1
- data/tmp/create_events_ok.rb +3 -1
- data/tmp/create_events_ok_fail_ack_ok.rb +3 -1
- data/tmp/create_events_ok_failure.rb +3 -1
- data/tmp/create_events_ok_failure_ack.rb +3 -1
- data/tmp/test_json_post.rb +5 -3
- data/tmp/test_notification_rules_api.rb +5 -3
- metadata +32 -61
- data/lib/flapjack/gateways/web/views/_foot.haml +0 -8
- data/lib/flapjack/gateways/web/views/_head.haml +0 -10
- data/lib/flapjack/gateways/web/views/_nav.haml +0 -14
- data/lib/flapjack/gateways/web/views/check.haml +0 -191
- data/lib/flapjack/gateways/web/views/checks.haml +0 -49
- data/lib/flapjack/gateways/web/views/contact.haml +0 -85
- data/lib/flapjack/gateways/web/views/contacts.haml +0 -30
- data/lib/flapjack/gateways/web/views/entities.haml +0 -28
- data/lib/flapjack/gateways/web/views/entity.haml +0 -50
- data/lib/flapjack/gateways/web/views/index.haml +0 -32
- data/lib/flapjack/gateways/web/views/self_stats.haml +0 -70
- data/spec/lib/flapjack/gateways/web/views/index.haml_spec.rb +0 -13
- data/spec/support/haml_view_helper.rb +0 -15
data/lib/flapjack/patches.rb
CHANGED
|
@@ -1,48 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
-
require 'ostruct'
|
|
4
3
|
require 'thin'
|
|
5
4
|
require 'resque'
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class OpenStruct
|
|
9
|
-
def to_h
|
|
10
|
-
@table
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
#module Log4r
|
|
15
|
-
# class Logger
|
|
16
|
-
# def error(args)
|
|
17
|
-
# err(args)
|
|
18
|
-
# end
|
|
19
|
-
#
|
|
20
|
-
# def warning(args)
|
|
21
|
-
# warn(args)
|
|
22
|
-
# end
|
|
23
|
-
# end
|
|
24
|
-
#end
|
|
25
|
-
|
|
26
|
-
# extracted from Extlib.
|
|
27
|
-
# FIXME: what's the licensing here?
|
|
28
|
-
class String
|
|
29
|
-
def camel_case
|
|
30
|
-
return self if self !~ /_/ && self =~ /[A-Z]+.*/
|
|
31
|
-
split('_').map{|e| e.capitalize}.join
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# http://gist.github.com/151324
|
|
36
|
-
class Hash
|
|
37
|
-
def symbolize_keys
|
|
38
|
-
inject({}) do |acc, (k,v)|
|
|
39
|
-
key = String === k ? k.to_sym : k
|
|
40
|
-
value = Hash === v ? v.symbolize_keys : v
|
|
41
|
-
acc[key] = value
|
|
42
|
-
acc
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
5
|
+
require 'redis'
|
|
46
6
|
|
|
47
7
|
# we don't want to stop the entire EM reactor when we stop a web server
|
|
48
8
|
# & @connections data type changed in thin 1.5.1
|
data/lib/flapjack/pikelet.rb
CHANGED
|
@@ -17,7 +17,8 @@ require 'em-resque'
|
|
|
17
17
|
require 'em-resque/worker'
|
|
18
18
|
require 'thin'
|
|
19
19
|
|
|
20
|
-
require 'flapjack/
|
|
20
|
+
require 'flapjack/notifier'
|
|
21
|
+
require 'flapjack/processor'
|
|
21
22
|
require 'flapjack/gateways/api'
|
|
22
23
|
require 'flapjack/gateways/jabber'
|
|
23
24
|
require 'flapjack/gateways/oobetet'
|
|
@@ -94,7 +95,8 @@ module Flapjack
|
|
|
94
95
|
|
|
95
96
|
class Generic < Flapjack::Pikelet::Base
|
|
96
97
|
|
|
97
|
-
PIKELET_TYPES = {'
|
|
98
|
+
PIKELET_TYPES = {'notifier' => Flapjack::Notifier,
|
|
99
|
+
'processor' => Flapjack::Processor,
|
|
98
100
|
'jabber' => Flapjack::Gateways::Jabber,
|
|
99
101
|
'pagerduty' => Flapjack::Gateways::Pagerduty,
|
|
100
102
|
'oobetet' => Flapjack::Gateways::Oobetet}
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
-
require 'log4r'
|
|
4
|
-
require 'log4r/outputter/fileoutputter'
|
|
5
|
-
require 'tzinfo'
|
|
6
|
-
require 'active_support/time'
|
|
7
|
-
|
|
8
|
-
require 'chronic'
|
|
9
3
|
require 'chronic_duration'
|
|
10
4
|
|
|
11
5
|
require 'flapjack/filters/acknowledgement'
|
|
@@ -14,19 +8,15 @@ require 'flapjack/filters/scheduled_maintenance'
|
|
|
14
8
|
require 'flapjack/filters/unscheduled_maintenance'
|
|
15
9
|
require 'flapjack/filters/detect_mass_client_failures'
|
|
16
10
|
require 'flapjack/filters/delays'
|
|
17
|
-
|
|
11
|
+
|
|
18
12
|
require 'flapjack/data/entity_check'
|
|
19
|
-
require 'flapjack/data/notification'
|
|
20
13
|
require 'flapjack/data/event'
|
|
21
14
|
require 'flapjack/redis_pool'
|
|
22
15
|
require 'flapjack/utility'
|
|
23
16
|
|
|
24
|
-
require 'flapjack/gateways/email'
|
|
25
|
-
require 'flapjack/gateways/sms_messagenet'
|
|
26
|
-
|
|
27
17
|
module Flapjack
|
|
28
18
|
|
|
29
|
-
class
|
|
19
|
+
class Processor
|
|
30
20
|
|
|
31
21
|
include Flapjack::Utility
|
|
32
22
|
|
|
@@ -36,29 +26,9 @@ module Flapjack
|
|
|
36
26
|
@logger = opts[:logger]
|
|
37
27
|
@redis = Flapjack::RedisPool.new(:config => @redis_config, :size => 2) # first will block
|
|
38
28
|
|
|
39
|
-
@
|
|
40
|
-
:sms => @config['sms_queue'],
|
|
41
|
-
:jabber => @config['jabber_queue'],
|
|
42
|
-
:pagerduty => @config['pagerduty_queue']}
|
|
29
|
+
@queue = @config['queue'] || 'events'
|
|
43
30
|
|
|
44
|
-
|
|
45
|
-
if not File.directory?(File.dirname(notifylog))
|
|
46
|
-
puts "Parent directory for log file #{notifylog} doesn't exist"
|
|
47
|
-
puts "Exiting!"
|
|
48
|
-
exit
|
|
49
|
-
end
|
|
50
|
-
@notifylog = Log4r::Logger.new("executive")
|
|
51
|
-
@notifylog.add(Log4r::FileOutputter.new("notifylog", :filename => notifylog))
|
|
52
|
-
|
|
53
|
-
tz = nil
|
|
54
|
-
tz_string = @config['default_contact_timezone'] || ENV['TZ'] || 'UTC'
|
|
55
|
-
begin
|
|
56
|
-
tz = ActiveSupport::TimeZone.new(tz_string)
|
|
57
|
-
rescue ArgumentError
|
|
58
|
-
logger.error("Invalid timezone string specified in default_contact_timezone or TZ (#{tz_string})")
|
|
59
|
-
exit 1
|
|
60
|
-
end
|
|
61
|
-
@default_contact_timezone = tz
|
|
31
|
+
@notifier_queue = @config['notifier_queue'] || 'notifications'
|
|
62
32
|
|
|
63
33
|
@archive_events = @config['archive_events'] || false
|
|
64
34
|
@events_archive_maxage = @config['events_archive_maxage']
|
|
@@ -66,8 +36,6 @@ module Flapjack
|
|
|
66
36
|
ncsm_duration_conf = @config['new_check_scheduled_maintenance_duration'] || '100 years'
|
|
67
37
|
@ncsm_duration = ChronicDuration.parse(ncsm_duration_conf)
|
|
68
38
|
|
|
69
|
-
# FIXME: Put loading filters into separate method
|
|
70
|
-
# FIXME: should we make the filters more configurable by the end user?
|
|
71
39
|
options = { :logger => opts[:logger], :redis => @redis }
|
|
72
40
|
@filters = []
|
|
73
41
|
@filters << Flapjack::Filters::Ok.new(options)
|
|
@@ -77,10 +45,10 @@ module Flapjack
|
|
|
77
45
|
@filters << Flapjack::Filters::Delays.new(options)
|
|
78
46
|
@filters << Flapjack::Filters::Acknowledgement.new(options)
|
|
79
47
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
@instance_id = "#{
|
|
48
|
+
boot_time = opts[:boot_time]
|
|
49
|
+
fqdn = `/bin/hostname -f`.chomp
|
|
50
|
+
pid = Process.pid
|
|
51
|
+
@instance_id = "#{fqdn}:#{pid}"
|
|
84
52
|
|
|
85
53
|
# FIXME: all of the below keys assume there is only ever one executive running;
|
|
86
54
|
# we could generate a fuid and save it to disk, and prepend it from that
|
|
@@ -94,8 +62,8 @@ module Flapjack
|
|
|
94
62
|
@redis.hset('event_counters', 'action', 0)
|
|
95
63
|
end
|
|
96
64
|
|
|
97
|
-
#@redis.zadd('executive_instances',
|
|
98
|
-
@redis.hset("executive_instance:#{@instance_id}", 'boot_time',
|
|
65
|
+
#@redis.zadd('executive_instances', boot_time.to_i, @instance_id)
|
|
66
|
+
@redis.hset("executive_instance:#{@instance_id}", 'boot_time', boot_time.to_i)
|
|
99
67
|
@redis.hset("event_counters:#{@instance_id}", 'all', 0)
|
|
100
68
|
@redis.hset("event_counters:#{@instance_id}", 'ok', 0)
|
|
101
69
|
@redis.hset("event_counters:#{@instance_id}", 'failure', 0)
|
|
@@ -122,7 +90,8 @@ module Flapjack
|
|
|
122
90
|
|
|
123
91
|
until @should_quit
|
|
124
92
|
@logger.debug("Waiting for event...")
|
|
125
|
-
event = Flapjack::Data::Event.next(
|
|
93
|
+
event = Flapjack::Data::Event.next(@queue,
|
|
94
|
+
:redis => @redis,
|
|
126
95
|
:archive_events => @archive_events,
|
|
127
96
|
:events_archive_maxage => @events_archive_maxage,
|
|
128
97
|
:logger => @logger)
|
|
@@ -136,10 +105,10 @@ module Flapjack
|
|
|
136
105
|
# from a different fiber while the main one is blocking.
|
|
137
106
|
def stop
|
|
138
107
|
@should_quit = true
|
|
139
|
-
@redis.rpush('events',
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
108
|
+
@redis.rpush('events', Oj.dump('type' => 'shutdown',
|
|
109
|
+
'host' => '',
|
|
110
|
+
'service' => '',
|
|
111
|
+
'state' => ''))
|
|
143
112
|
end
|
|
144
113
|
|
|
145
114
|
private
|
|
@@ -160,15 +129,15 @@ module Flapjack
|
|
|
160
129
|
should_notify = update_keys(event, entity_check, timestamp)
|
|
161
130
|
|
|
162
131
|
if !should_notify
|
|
163
|
-
@logger.debug("Not generating
|
|
132
|
+
@logger.debug("Not generating notification for event #{event.id} because filtering was skipped")
|
|
164
133
|
return
|
|
165
134
|
elsif blocker = @filters.find {|filter| filter.block?(event) }
|
|
166
|
-
@logger.debug("Not generating
|
|
135
|
+
@logger.debug("Not generating notification for event #{event.id} because this filter blocked: #{blocker.name}")
|
|
167
136
|
return
|
|
168
137
|
end
|
|
169
138
|
|
|
170
|
-
@logger.info("Generating
|
|
171
|
-
|
|
139
|
+
@logger.info("Generating notification for event #{event_str}")
|
|
140
|
+
generate_notification(event, entity_check, timestamp)
|
|
172
141
|
end
|
|
173
142
|
|
|
174
143
|
def update_keys(event, entity_check, timestamp)
|
|
@@ -177,7 +146,7 @@ module Flapjack
|
|
|
177
146
|
|
|
178
147
|
result = true
|
|
179
148
|
|
|
180
|
-
|
|
149
|
+
event.counter = @redis.hincrby('event_counters', 'all', 1)
|
|
181
150
|
@redis.hincrby("event_counters:#{@instance_id}", 'all', 1)
|
|
182
151
|
|
|
183
152
|
# FIXME skip if entity_check.nil?
|
|
@@ -197,7 +166,7 @@ module Flapjack
|
|
|
197
166
|
elsif event.failure?
|
|
198
167
|
@redis.hincrby('event_counters', 'failure', 1)
|
|
199
168
|
@redis.hincrby("event_counters:#{@instance_id}", 'failure', 1)
|
|
200
|
-
@redis.hset('unacknowledged_failures',
|
|
169
|
+
@redis.hset('unacknowledged_failures', event.counter, event.id)
|
|
201
170
|
end
|
|
202
171
|
|
|
203
172
|
event.previous_state = entity_check.state
|
|
@@ -207,8 +176,8 @@ module Flapjack
|
|
|
207
176
|
|
|
208
177
|
if @ncsm_duration >= 0
|
|
209
178
|
@logger.info("Setting scheduled maintenance for #{time_period_in_words(@ncsm_duration)}")
|
|
210
|
-
entity_check.create_scheduled_maintenance(
|
|
211
|
-
|
|
179
|
+
entity_check.create_scheduled_maintenance(timestamp,
|
|
180
|
+
@ncsm_duration, :summary => 'Automatically created for new check')
|
|
212
181
|
end
|
|
213
182
|
else
|
|
214
183
|
event.previous_state_duration = timestamp - entity_check.last_change.to_i
|
|
@@ -216,7 +185,7 @@ module Flapjack
|
|
|
216
185
|
|
|
217
186
|
entity_check.update_state(event.state, :timestamp => timestamp,
|
|
218
187
|
:summary => event.summary, :client => event.client,
|
|
219
|
-
:count =>
|
|
188
|
+
:count => event.counter, :details => event.details)
|
|
220
189
|
|
|
221
190
|
# No state change, and event is ok, so no need to run through filters
|
|
222
191
|
# OR
|
|
@@ -244,27 +213,8 @@ module Flapjack
|
|
|
244
213
|
result
|
|
245
214
|
end
|
|
246
215
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
def generate_notification_messages(event, entity_check, timestamp)
|
|
250
|
-
notification_type = 'unknown'
|
|
251
|
-
case event.type
|
|
252
|
-
when 'service'
|
|
253
|
-
case event.state
|
|
254
|
-
when 'ok'
|
|
255
|
-
notification_type = 'recovery'
|
|
256
|
-
when 'warning', 'critical', 'unknown'
|
|
257
|
-
notification_type = 'problem'
|
|
258
|
-
end
|
|
259
|
-
when 'action'
|
|
260
|
-
case event.state
|
|
261
|
-
when 'acknowledgement'
|
|
262
|
-
notification_type = 'acknowledgement'
|
|
263
|
-
when 'test_notifications'
|
|
264
|
-
notification_type = 'test'
|
|
265
|
-
end
|
|
266
|
-
end
|
|
267
|
-
|
|
216
|
+
def generate_notification(event, entity_check, timestamp)
|
|
217
|
+
notification_type = Flapjack::Data::Notification.type_for_event(event)
|
|
268
218
|
max_notified_severity = entity_check.max_notified_severity_of_current_failure
|
|
269
219
|
|
|
270
220
|
@redis.set("#{event.id}:last_#{notification_type}_notification", timestamp)
|
|
@@ -273,75 +223,12 @@ module Flapjack
|
|
|
273
223
|
@redis.rpush("#{event.id}:#{event.state}_notifications", timestamp) if event.failure?
|
|
274
224
|
@logger.debug("Notification of type #{notification_type} is being generated for #{event.id}.")
|
|
275
225
|
|
|
276
|
-
|
|
226
|
+
severity = Flapjack::Data::Notification.severity_for_event(event, max_notified_severity)
|
|
227
|
+
last_state = entity_check.historical_state_before(timestamp)
|
|
277
228
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
return
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
notification = Flapjack::Data::Notification.for_event(
|
|
285
|
-
event, :type => notification_type,
|
|
286
|
-
:max_notified_severity => max_notified_severity,
|
|
287
|
-
:contacts => contacts,
|
|
288
|
-
:default_timezone => @default_contact_timezone,
|
|
289
|
-
:last_state => entity_check.historical_state_before(timestamp),
|
|
290
|
-
:logger => @logger)
|
|
291
|
-
|
|
292
|
-
notification.messages.each do |message|
|
|
293
|
-
media_type = message.medium
|
|
294
|
-
contents = message.contents
|
|
295
|
-
address = message.address
|
|
296
|
-
event_id = event.id
|
|
297
|
-
|
|
298
|
-
@notifylog.info("#{Time.at(timestamp).to_s} | #{event_id} | " +
|
|
299
|
-
"#{notification_type} | #{message.contact.id} | #{media_type} | #{address}")
|
|
300
|
-
|
|
301
|
-
unless @queues[media_type.to_sym]
|
|
302
|
-
@logger.error("no queue for media type: #{media_type}")
|
|
303
|
-
return
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
@logger.info("Enqueueing #{media_type} alert for #{event_id} to #{address}")
|
|
307
|
-
|
|
308
|
-
if event.ok?
|
|
309
|
-
message.contact.update_sent_alert_keys(
|
|
310
|
-
:media => media_type,
|
|
311
|
-
:check => event_id,
|
|
312
|
-
:state => 'warning',
|
|
313
|
-
:delete => true)
|
|
314
|
-
message.contact.update_sent_alert_keys(
|
|
315
|
-
:media => media_type,
|
|
316
|
-
:check => event_id,
|
|
317
|
-
:state => 'critical',
|
|
318
|
-
:delete => true)
|
|
319
|
-
message.contact.update_sent_alert_keys(
|
|
320
|
-
:media => media_type,
|
|
321
|
-
:check => event_id,
|
|
322
|
-
:state => 'unknown',
|
|
323
|
-
:delete => true)
|
|
324
|
-
else
|
|
325
|
-
message.contact.update_sent_alert_keys(
|
|
326
|
-
:media => media_type,
|
|
327
|
-
:check => event_id,
|
|
328
|
-
:state => event.state)
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
# TODO consider changing Resque jobs to use raw blpop like the others
|
|
332
|
-
case media_type.to_sym
|
|
333
|
-
when :sms
|
|
334
|
-
Resque.enqueue_to(@queues[:sms], Flapjack::Gateways::SmsMessagenet, contents)
|
|
335
|
-
when :email
|
|
336
|
-
Resque.enqueue_to(@queues[:email], Flapjack::Gateways::Email, contents)
|
|
337
|
-
when :jabber
|
|
338
|
-
# TODO move next line up into other notif value setting above?
|
|
339
|
-
contents['event_count'] = @event_count if @event_count
|
|
340
|
-
@redis.rpush(@queues[:jabber], Yajl::Encoder.encode(contents))
|
|
341
|
-
when :pagerduty
|
|
342
|
-
@redis.rpush(@queues[:pagerduty], Yajl::Encoder.encode(contents))
|
|
343
|
-
end
|
|
344
|
-
end
|
|
229
|
+
Flapjack::Data::Notification.add(@notifier_queue, event,
|
|
230
|
+
:type => notification_type, :severity => severity, :last_state => last_state,
|
|
231
|
+
:redis => @redis)
|
|
345
232
|
end
|
|
346
233
|
|
|
347
234
|
end
|
data/lib/flapjack/version.rb
CHANGED
|
@@ -7,91 +7,154 @@ describe Flapjack::Coordinator do
|
|
|
7
7
|
let(:fiber) { mock(Fiber) }
|
|
8
8
|
let(:config) { mock(Flapjack::Configuration) }
|
|
9
9
|
|
|
10
|
-
let(:logger) { mock(Logger) }
|
|
11
|
-
let(:stdout_out) { mock('stdout_out') }
|
|
12
|
-
let(:syslog_out) { mock('syslog_out') }
|
|
10
|
+
let(:logger) { mock(Flapjack::Logger) }
|
|
13
11
|
|
|
14
12
|
let!(:time) { Time.now }
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
it "starts and stops a pikelet" do
|
|
15
|
+
Flapjack::Logger.should_receive(:new).and_return(logger)
|
|
16
|
+
|
|
17
|
+
cfg = {'processor' => {'enabled' => true}}
|
|
18
|
+
EM.should_receive(:synchrony).and_yield
|
|
19
|
+
config.should_receive(:for_redis).and_return({})
|
|
20
|
+
config.should_receive(:all).and_return(cfg)
|
|
21
|
+
|
|
22
|
+
processor = mock('processor')
|
|
23
|
+
processor.should_receive(:start)
|
|
24
|
+
processor.should_receive(:stop)
|
|
25
|
+
processor.should_receive(:update_status)
|
|
26
|
+
processor.should_receive(:status).exactly(3).times.and_return('stopped')
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
|
|
28
|
+
Time.should_receive(:now).and_return(time)
|
|
29
|
+
|
|
30
|
+
fc = Flapjack::Coordinator.new(config)
|
|
31
|
+
Flapjack::Pikelet.should_receive(:create).with('processor',
|
|
32
|
+
:config => cfg['processor'], :redis_config => {}, :boot_time => time).
|
|
33
|
+
and_return(processor)
|
|
34
|
+
|
|
35
|
+
fiber.should_receive(:resume)
|
|
36
|
+
Fiber.should_receive(:new).and_yield.and_return(fiber)
|
|
24
37
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
38
|
+
EM.should_receive(:stop)
|
|
39
|
+
|
|
40
|
+
# Syslog.should_receive(:opened?).and_return(true)
|
|
41
|
+
# Syslog.should_receive(:close)
|
|
42
|
+
|
|
43
|
+
fc.start(:signals => false)
|
|
44
|
+
fc.stop
|
|
30
45
|
end
|
|
31
46
|
|
|
32
|
-
it "
|
|
33
|
-
|
|
47
|
+
it "handles an exception raised by a pikelet and shuts down" do
|
|
48
|
+
Flapjack::Logger.should_receive(:new).and_return(logger)
|
|
49
|
+
logger.should_receive(:fatal)
|
|
34
50
|
|
|
35
|
-
cfg = {'
|
|
51
|
+
cfg = {'processor' => {'enabled' => true}}
|
|
36
52
|
EM.should_receive(:synchrony).and_yield
|
|
37
53
|
config.should_receive(:for_redis).and_return({})
|
|
38
54
|
config.should_receive(:all).and_return(cfg)
|
|
39
55
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
56
|
+
processor = mock('processor')
|
|
57
|
+
processor.should_receive(:start).and_raise(RuntimeError)
|
|
58
|
+
processor.should_receive(:stop)
|
|
59
|
+
processor.should_receive(:update_status)
|
|
60
|
+
processor.should_receive(:status).exactly(3).times.and_return('stopped')
|
|
45
61
|
|
|
46
62
|
Time.should_receive(:now).and_return(time)
|
|
47
63
|
|
|
48
64
|
fc = Flapjack::Coordinator.new(config)
|
|
49
|
-
Flapjack::Pikelet.should_receive(:create).with('
|
|
50
|
-
:config => cfg['
|
|
51
|
-
and_return(
|
|
65
|
+
Flapjack::Pikelet.should_receive(:create).with('processor',
|
|
66
|
+
:config => cfg['processor'], :redis_config => {}, :boot_time => time)
|
|
67
|
+
.and_return(processor)
|
|
52
68
|
|
|
53
69
|
fiber.should_receive(:resume)
|
|
54
70
|
Fiber.should_receive(:new).and_yield.and_return(fiber)
|
|
55
71
|
|
|
56
72
|
EM.should_receive(:stop)
|
|
57
73
|
|
|
74
|
+
# Syslog.should_receive(:opened?).and_return(true)
|
|
75
|
+
# Syslog.should_receive(:close)
|
|
76
|
+
|
|
58
77
|
fc.start(:signals => false)
|
|
59
78
|
fc.stop
|
|
60
79
|
end
|
|
61
80
|
|
|
62
|
-
it "
|
|
63
|
-
|
|
64
|
-
|
|
81
|
+
it "loads an old executive pikelet config block with no new data" do
|
|
82
|
+
cfg = {'executive' => {'enabled' => true}}
|
|
83
|
+
EM.should_receive(:synchrony).and_yield
|
|
84
|
+
config.should_receive(:for_redis).and_return({})
|
|
85
|
+
config.should_receive(:all).and_return(cfg)
|
|
86
|
+
|
|
87
|
+
processor = mock('processor')
|
|
88
|
+
processor.should_receive(:start)
|
|
89
|
+
processor.should_receive(:stop)
|
|
90
|
+
processor.should_receive(:update_status)
|
|
91
|
+
processor.should_receive(:status).exactly(3).times.and_return('stopped')
|
|
92
|
+
|
|
93
|
+
notifier = mock('processor')
|
|
94
|
+
notifier.should_receive(:start)
|
|
95
|
+
notifier.should_receive(:stop)
|
|
96
|
+
notifier.should_receive(:update_status)
|
|
97
|
+
notifier.should_receive(:status).exactly(3).times.and_return('stopped')
|
|
98
|
+
|
|
99
|
+
Time.should_receive(:now).and_return(time)
|
|
100
|
+
|
|
101
|
+
fc = Flapjack::Coordinator.new(config)
|
|
102
|
+
Flapjack::Pikelet.should_receive(:create).with('processor',
|
|
103
|
+
:config => cfg['executive'], :redis_config => {}, :boot_time => time).
|
|
104
|
+
and_return(processor)
|
|
105
|
+
Flapjack::Pikelet.should_receive(:create).with('notifier',
|
|
106
|
+
:config => cfg['executive'], :redis_config => {}, :boot_time => time).
|
|
107
|
+
and_return(notifier)
|
|
65
108
|
|
|
66
|
-
|
|
109
|
+
fiber.should_receive(:resume)
|
|
110
|
+
Fiber.should_receive(:new).and_yield.and_return(fiber)
|
|
111
|
+
|
|
112
|
+
EM.should_receive(:stop)
|
|
113
|
+
|
|
114
|
+
# Syslog.should_receive(:opened?).and_return(true)
|
|
115
|
+
# Syslog.should_receive(:close)
|
|
116
|
+
|
|
117
|
+
fc.start(:signals => false)
|
|
118
|
+
fc.stop
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it "loads an old executive pikelet config block with some new data" do
|
|
122
|
+
cfg = {'executive' => {'enabled' => true},
|
|
123
|
+
'processor' => {'foo' => 'bar'},
|
|
124
|
+
'notifier' => {'enabled' => false}
|
|
125
|
+
}
|
|
67
126
|
EM.should_receive(:synchrony).and_yield
|
|
68
127
|
config.should_receive(:for_redis).and_return({})
|
|
69
128
|
config.should_receive(:all).and_return(cfg)
|
|
70
129
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
130
|
+
processor = mock('processor')
|
|
131
|
+
processor.should_receive(:start)
|
|
132
|
+
processor.should_receive(:stop)
|
|
133
|
+
processor.should_receive(:update_status)
|
|
134
|
+
processor.should_receive(:status).exactly(3).times.and_return('stopped')
|
|
76
135
|
|
|
77
136
|
Time.should_receive(:now).and_return(time)
|
|
78
137
|
|
|
79
138
|
fc = Flapjack::Coordinator.new(config)
|
|
80
|
-
Flapjack::Pikelet.should_receive(:create).with('
|
|
81
|
-
:config => cfg['executive'],
|
|
82
|
-
|
|
139
|
+
Flapjack::Pikelet.should_receive(:create).with('processor',
|
|
140
|
+
:config => cfg['executive'].merge(cfg['processor']),
|
|
141
|
+
:redis_config => {}, :boot_time => time).
|
|
142
|
+
and_return(processor)
|
|
83
143
|
|
|
84
144
|
fiber.should_receive(:resume)
|
|
85
145
|
Fiber.should_receive(:new).and_yield.and_return(fiber)
|
|
86
146
|
|
|
87
147
|
EM.should_receive(:stop)
|
|
88
148
|
|
|
149
|
+
# Syslog.should_receive(:opened?).and_return(true)
|
|
150
|
+
# Syslog.should_receive(:close)
|
|
151
|
+
|
|
89
152
|
fc.start(:signals => false)
|
|
90
153
|
fc.stop
|
|
91
154
|
end
|
|
92
155
|
|
|
93
156
|
it "traps system signals and shuts down" do
|
|
94
|
-
|
|
157
|
+
Flapjack::Logger.should_receive(:new).and_return(logger)
|
|
95
158
|
|
|
96
159
|
RbConfig::CONFIG.should_receive(:[]).with('host_os').and_return('darwin12.0.0')
|
|
97
160
|
|
|
@@ -109,7 +172,7 @@ describe Flapjack::Coordinator do
|
|
|
109
172
|
end
|
|
110
173
|
|
|
111
174
|
it "only traps two system signals on Windows" do
|
|
112
|
-
|
|
175
|
+
Flapjack::Logger.should_receive(:new).and_return(logger)
|
|
113
176
|
|
|
114
177
|
RbConfig::CONFIG.should_receive(:[]).with('host_os').and_return('mswin')
|
|
115
178
|
|
|
@@ -126,10 +189,10 @@ describe Flapjack::Coordinator do
|
|
|
126
189
|
end
|
|
127
190
|
|
|
128
191
|
it "stops one pikelet and starts another on reload" do
|
|
129
|
-
|
|
192
|
+
Flapjack::Logger.should_receive(:new).and_return(logger)
|
|
130
193
|
|
|
131
|
-
old_cfg = {'
|
|
132
|
-
new_cfg = {'gateways' => {'jabber' => {'enabled' =>
|
|
194
|
+
old_cfg = {'processor' => {'enabled' => true}}
|
|
195
|
+
new_cfg = {'gateways' => {'jabber' => {'enabled' => true}}}
|
|
133
196
|
|
|
134
197
|
new_config = mock('new_config')
|
|
135
198
|
filename = mock('filename')
|
|
@@ -141,15 +204,15 @@ describe Flapjack::Coordinator do
|
|
|
141
204
|
new_config.should_receive(:load).with(filename)
|
|
142
205
|
new_config.should_receive(:all).and_return(new_cfg)
|
|
143
206
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
207
|
+
processor = mock('processor')
|
|
208
|
+
processor.should_receive(:type).twice.and_return('processor')
|
|
209
|
+
processor.should_receive(:stop)
|
|
210
|
+
processor.should_receive(:update_status)
|
|
211
|
+
processor.should_receive(:status).exactly(3).times.and_return('stopped')
|
|
149
212
|
|
|
150
213
|
jabber = mock('jabber')
|
|
151
214
|
Flapjack::Pikelet.should_receive(:create).
|
|
152
|
-
with('jabber', :config => {"enabled" =>
|
|
215
|
+
with('jabber', :config => {"enabled" => true}, :redis_config => {},
|
|
153
216
|
:boot_time => time).
|
|
154
217
|
and_return(jabber)
|
|
155
218
|
jabber.should_receive(:start)
|
|
@@ -160,16 +223,16 @@ describe Flapjack::Coordinator do
|
|
|
160
223
|
config.should_receive(:for_redis).and_return({})
|
|
161
224
|
fc = Flapjack::Coordinator.new(config)
|
|
162
225
|
fc.instance_variable_set('@boot_time', time)
|
|
163
|
-
fc.instance_variable_set('@pikelets', [
|
|
226
|
+
fc.instance_variable_set('@pikelets', [processor])
|
|
164
227
|
fc.reload
|
|
165
228
|
fc.instance_variable_get('@pikelets').should == [jabber]
|
|
166
229
|
end
|
|
167
230
|
|
|
168
231
|
it "reloads a pikelet config without restarting it" do
|
|
169
|
-
|
|
232
|
+
Flapjack::Logger.should_receive(:new).and_return(logger)
|
|
170
233
|
|
|
171
|
-
old_cfg = {'
|
|
172
|
-
new_cfg = {'
|
|
234
|
+
old_cfg = {'processor' => {'enabled' => true, 'foo' => 'bar'}}
|
|
235
|
+
new_cfg = {'processor' => {'enabled' => true, 'foo' => 'baz'}}
|
|
173
236
|
|
|
174
237
|
new_config = mock('new_config')
|
|
175
238
|
filename = mock('filename')
|
|
@@ -181,25 +244,25 @@ describe Flapjack::Coordinator do
|
|
|
181
244
|
new_config.should_receive(:load).with(filename)
|
|
182
245
|
new_config.should_receive(:all).and_return(new_cfg)
|
|
183
246
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
247
|
+
processor = mock('processor')
|
|
248
|
+
processor.should_not_receive(:start)
|
|
249
|
+
processor.should_receive(:type).exactly(3).times.and_return('processor')
|
|
250
|
+
processor.should_receive(:reload).with(new_cfg['processor']).and_return(true)
|
|
251
|
+
processor.should_not_receive(:stop)
|
|
189
252
|
|
|
190
253
|
config.should_receive(:for_redis).and_return({})
|
|
191
254
|
fc = Flapjack::Coordinator.new(config)
|
|
192
255
|
fc.instance_variable_set('@boot_time', time)
|
|
193
|
-
fc.instance_variable_set('@pikelets', [
|
|
256
|
+
fc.instance_variable_set('@pikelets', [processor])
|
|
194
257
|
fc.reload
|
|
195
|
-
fc.instance_variable_get('@pikelets').should == [
|
|
258
|
+
fc.instance_variable_get('@pikelets').should == [processor]
|
|
196
259
|
end
|
|
197
260
|
|
|
198
261
|
it "reloads a pikelet config while restarting it" do
|
|
199
|
-
|
|
262
|
+
Flapjack::Logger.should_receive(:new).and_return(logger)
|
|
200
263
|
|
|
201
|
-
old_cfg = {'
|
|
202
|
-
new_cfg = {'
|
|
264
|
+
old_cfg = {'processor' => {'enabled' => true, 'foo' => 'bar'}}
|
|
265
|
+
new_cfg = {'processor' => {'enabled' => true, 'baz' => 'qux'}}
|
|
203
266
|
|
|
204
267
|
new_config = mock('new_config')
|
|
205
268
|
filename = mock('filename')
|
|
@@ -211,12 +274,12 @@ describe Flapjack::Coordinator do
|
|
|
211
274
|
new_config.should_receive(:load).with(filename)
|
|
212
275
|
new_config.should_receive(:all).and_return(new_cfg)
|
|
213
276
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
277
|
+
processor = mock('processor')
|
|
278
|
+
processor.should_receive(:type).exactly(5).times.and_return('processor')
|
|
279
|
+
processor.should_receive(:reload).with(new_cfg['processor']).and_return(false)
|
|
280
|
+
processor.should_receive(:stop)
|
|
281
|
+
processor.should_receive(:update_status)
|
|
282
|
+
processor.should_receive(:status).exactly(3).times.and_return('stopped')
|
|
220
283
|
|
|
221
284
|
fiber.should_receive(:resume)
|
|
222
285
|
Fiber.should_receive(:new).and_yield.and_return(fiber)
|
|
@@ -225,14 +288,14 @@ describe Flapjack::Coordinator do
|
|
|
225
288
|
new_exec.should_receive(:start)
|
|
226
289
|
|
|
227
290
|
Flapjack::Pikelet.should_receive(:create).
|
|
228
|
-
with('
|
|
291
|
+
with('processor', :config => new_cfg['processor'], :redis_config => {},
|
|
229
292
|
:boot_time => time).
|
|
230
293
|
and_return(new_exec)
|
|
231
294
|
|
|
232
295
|
config.should_receive(:for_redis).and_return({})
|
|
233
296
|
fc = Flapjack::Coordinator.new(config)
|
|
234
297
|
fc.instance_variable_set('@boot_time', time)
|
|
235
|
-
fc.instance_variable_set('@pikelets', [
|
|
298
|
+
fc.instance_variable_set('@pikelets', [processor])
|
|
236
299
|
fc.reload
|
|
237
300
|
fc.instance_variable_get('@pikelets').should == [new_exec]
|
|
238
301
|
end
|