flapjack 0.7.20 → 0.7.21
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.travis.yml +3 -1
- data/CHANGELOG.md +10 -0
- data/Gemfile +1 -0
- data/bin/flapjack +11 -0
- data/bin/simulate-failed-check +5 -5
- data/features/notification_rules.feature +77 -19
- data/features/steps/events_steps.rb +15 -3
- data/lib/flapjack/coordinator.rb +3 -3
- data/lib/flapjack/data/contact.rb +1 -1
- data/lib/flapjack/data/entity.rb +12 -1
- data/lib/flapjack/data/entity_check.rb +9 -2
- data/lib/flapjack/data/event.rb +4 -4
- data/lib/flapjack/data/notification.rb +27 -20
- data/lib/flapjack/data/notification_rule.rb +26 -24
- data/lib/flapjack/data/tag.rb +5 -0
- data/lib/flapjack/gateways/api.rb +1 -1
- data/lib/flapjack/gateways/api/contact_methods.rb +3 -3
- data/lib/flapjack/gateways/email.rb +73 -46
- data/lib/flapjack/gateways/email/alert.html.erb +13 -4
- data/lib/flapjack/gateways/email/alert.text.erb +2 -2
- data/lib/flapjack/gateways/jabber.rb +22 -16
- data/lib/flapjack/gateways/pagerduty.rb +7 -3
- data/lib/flapjack/gateways/web.rb +1 -1
- data/lib/flapjack/gateways/web/views/check.html.erb +2 -2
- data/lib/flapjack/gateways/web/views/contact.html.erb +3 -3
- data/lib/flapjack/logger.rb +67 -35
- data/lib/flapjack/notifier.rb +9 -3
- data/lib/flapjack/pikelet.rb +3 -1
- data/lib/flapjack/processor.rb +34 -10
- data/lib/flapjack/version.rb +1 -1
- data/spec/lib/flapjack/coordinator_spec.rb +17 -13
- data/spec/lib/flapjack/data/contact_spec.rb +4 -3
- data/spec/lib/flapjack/data/entity_check_spec.rb +10 -0
- data/spec/lib/flapjack/data/entity_spec.rb +60 -5
- data/spec/lib/flapjack/data/event_spec.rb +4 -4
- data/spec/lib/flapjack/data/notification_rule_spec.rb +9 -2
- data/spec/lib/flapjack/data/tag_spec.rb +0 -1
- data/spec/lib/flapjack/gateways/api/contact_methods_spec.rb +1 -1
- data/spec/lib/flapjack/gateways/email_spec.rb +2 -1
- data/spec/lib/flapjack/gateways/jabber_spec.rb +5 -3
- data/spec/lib/flapjack/gateways/pagerduty_spec.rb +3 -1
- data/spec/lib/flapjack/logger_spec.rb +5 -5
- data/spec/lib/flapjack/pikelet_spec.rb +4 -2
- data/spec/lib/flapjack/processor_spec.rb +16 -7
- data/tasks/benchmarks.rake +228 -0
- data/tasks/events.rake +11 -10
- data/tasks/support/flapjack_config_benchmark.yaml +58 -0
- metadata +6 -4
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -2,6 +2,8 @@ language: ruby
|
|
2
2
|
rvm:
|
3
3
|
- "1.9.3"
|
4
4
|
- "2.0.0"
|
5
|
+
env:
|
6
|
+
- ENTITIES=10 INTERVAL=120
|
5
7
|
gemfile:
|
6
8
|
- Gemfile
|
7
9
|
services:
|
@@ -11,4 +13,4 @@ before_script:
|
|
11
13
|
before_install:
|
12
14
|
- git submodule update --init --recursive
|
13
15
|
- gem install bundler
|
14
|
-
script: bundle exec rspec spec && bundle exec cucumber features
|
16
|
+
script: bundle exec rspec spec && bundle exec cucumber features && bundle exec rake benchmarks:run
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
## Flapjack Changelog
|
2
2
|
|
3
|
+
# 0.7.21 - 2013-08-08
|
4
|
+
- Feature: make eneity search scopable by tags gh-89 (@jessereynolds)
|
5
|
+
- Feature: add benchmark rake task gh-259 (@jessereynolds)
|
6
|
+
- Feature: make tags more general in notification rules gh-269 (@jessereynolds)
|
7
|
+
- Feature: ephemeral tag generation on events gh-268 (@jessereynolds)
|
8
|
+
- Bug: fix syslog output levels gh-260 (@ali-graham)
|
9
|
+
- Bug: Ruby 2 shutdown error gh-261 (@ali-graham)
|
10
|
+
- Bug: Email and SMS problem and recovery notifications failing (@jessereynolds)
|
11
|
+
- Bug: Links to contacts from the check detail page are broken (@jessereynolds)
|
12
|
+
|
3
13
|
# 0.7.20 - 2013-07-17
|
4
14
|
- Bug: flapjack-nagios-receiver failing after json library change gh-257 (@jessereynolds)
|
5
15
|
- Bug: email gateway partial conversion to erb sending haml source code gh-256 (@ali-graham)
|
data/Gemfile
CHANGED
data/bin/flapjack
CHANGED
@@ -6,6 +6,17 @@ unless $:.include?(File.dirname(__FILE__) + '/../lib/')
|
|
6
6
|
end
|
7
7
|
|
8
8
|
require 'dante'
|
9
|
+
|
10
|
+
module Dante
|
11
|
+
class Runner
|
12
|
+
|
13
|
+
def start
|
14
|
+
# skip signal traps
|
15
|
+
@startup_command.call(self.options) if @startup_command
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
9
20
|
require 'optparse'
|
10
21
|
require 'ostruct'
|
11
22
|
|
data/bin/simulate-failed-check
CHANGED
@@ -12,6 +12,7 @@ require 'eventmachine'
|
|
12
12
|
require 'json'
|
13
13
|
|
14
14
|
require 'flapjack/configuration'
|
15
|
+
require 'flapjack/data/event'
|
15
16
|
|
16
17
|
def pike(message)
|
17
18
|
puts "piking out: #{message}"
|
@@ -20,7 +21,7 @@ end
|
|
20
21
|
|
21
22
|
def send_event(event, opts)
|
22
23
|
redis = opts[:redis]
|
23
|
-
|
24
|
+
Flapjack::Data::Event.add(event, :redis => redis)
|
24
25
|
end
|
25
26
|
|
26
27
|
def fail(opts)
|
@@ -31,8 +32,7 @@ def fail(opts)
|
|
31
32
|
event = {
|
32
33
|
'entity' => opts[:entity] || 'foo-app-01',
|
33
34
|
'check' => opts[:check] || 'HTTP',
|
34
|
-
'type' => 'service'
|
35
|
-
'timestamp' => Time.now.to_i
|
35
|
+
'type' => 'service'
|
36
36
|
}
|
37
37
|
failure = event.merge('state' => state, 'summary' => 'Simulated check output (test by operator)')
|
38
38
|
recovery = event.merge('state' => 'ok', 'summary' => 'Simulated check output (test by operator)')
|
@@ -47,14 +47,14 @@ def fail(opts)
|
|
47
47
|
puts "#{Time.now}: stopping"
|
48
48
|
if recover
|
49
49
|
puts "#{Time.now}: sending recovery event for #{key}"
|
50
|
-
send_event(recovery, :redis => redis)
|
50
|
+
send_event(recovery.merge('time' => Time.now.to_i), :redis => redis)
|
51
51
|
end
|
52
52
|
EM.stop
|
53
53
|
end
|
54
54
|
|
55
55
|
EM.add_periodic_timer(10) do
|
56
56
|
puts "#{Time.now}: sending failure event (#{state}) for #{key}"
|
57
|
-
send_event(failure, :redis => redis)
|
57
|
+
send_event(failure.merge('time' => Time.now.to_i), :redis => redis)
|
58
58
|
end
|
59
59
|
|
60
60
|
}
|
@@ -7,13 +7,15 @@ Feature: Notification rules on a per contact basis
|
|
7
7
|
| 1 | Malak | Al-Musawi | malak@example.com | +61400000001 | Asia/Baghdad |
|
8
8
|
| 2 | Imani | Farooq | imani@example.com | +61400000002 | Europe/Moscow |
|
9
9
|
| 3 | Vera | Дурейко | vera@example.com | +61400000003 | Europe/Paris |
|
10
|
+
| 4 | Lucia | Moretti | lucia@example.com | +61400000004 | Europe/Rome |
|
10
11
|
|
11
12
|
And the following entities exist:
|
12
|
-
| id | name
|
13
|
-
| 1 | foo
|
14
|
-
| 2 | bar
|
15
|
-
| 3 | baz
|
16
|
-
| 4 | buf
|
13
|
+
| id | name | contacts |
|
14
|
+
| 1 | foo | 1 |
|
15
|
+
| 2 | bar | 1,2,3 |
|
16
|
+
| 3 | baz | 1,3 |
|
17
|
+
| 4 | buf | 1,2,3 |
|
18
|
+
| 5 | foo-app-01.xyz | 4 |
|
17
19
|
|
18
20
|
And user 1 has the following notification intervals:
|
19
21
|
| email | sms |
|
@@ -27,25 +29,35 @@ Feature: Notification rules on a per contact basis
|
|
27
29
|
| email | sms |
|
28
30
|
| 15 | 60 |
|
29
31
|
|
32
|
+
And user 4 has the following notification intervals:
|
33
|
+
| email | sms |
|
34
|
+
| 15 | 60 |
|
35
|
+
|
30
36
|
And user 1 has the following notification rules:
|
31
|
-
| entities |
|
32
|
-
| |
|
33
|
-
| foo |
|
34
|
-
| bar |
|
35
|
-
| baz |
|
37
|
+
| entities | tags | warning_media | critical_media | warning_blackhole | critical_blackhole | time_restrictions |
|
38
|
+
| | | email | sms,email | true | true | |
|
39
|
+
| foo | | email | sms,email | | | 8-18 weekdays |
|
40
|
+
| bar | | | sms,email | true | | |
|
41
|
+
| baz | | email | sms,email | | | |
|
36
42
|
|
37
43
|
And user 2 has the following notification rules:
|
38
|
-
| entities |
|
39
|
-
| |
|
40
|
-
| |
|
41
|
-
| bar |
|
44
|
+
| entities | tags | warning_media | critical_media | warning_blackhole | critical_blackhole | time_restrictions |
|
45
|
+
| | | email | email | | | |
|
46
|
+
| | | sms | sms | | | |
|
47
|
+
| bar | | email | email,sms | | | |
|
42
48
|
|
43
49
|
And user 3 has the following notification rules:
|
44
|
-
| entities |
|
45
|
-
| |
|
46
|
-
| baz |
|
47
|
-
| buf |
|
48
|
-
| buf |
|
50
|
+
| entities | tags | warning_media | critical_media | warning_blackhole | critical_blackhole | time_restrictions |
|
51
|
+
| | | email | email | | | |
|
52
|
+
| baz | | sms | sms | | | |
|
53
|
+
| buf | | email | email | | | |
|
54
|
+
| buf | | sms | sms | | | |
|
55
|
+
|
56
|
+
And user 4 has the following notification rules:
|
57
|
+
| entities | tags | warning_media | critical_media | warning_blackhole | critical_blackhole | time_restrictions |
|
58
|
+
| | | | | | | |
|
59
|
+
| | xyz, disk, util | sms | sms | | | |
|
60
|
+
| | xyz, ping | sms,email | sms,email | | | 8-18 weekdays |
|
49
61
|
|
50
62
|
@time_restrictions @time
|
51
63
|
Scenario: Alerts only during specified time restrictions
|
@@ -310,3 +322,49 @@ Feature: Notification rules on a per contact basis
|
|
310
322
|
@time
|
311
323
|
Scenario: A blackhole rule on an entity should override another matching general rule
|
312
324
|
|
325
|
+
@time
|
326
|
+
Scenario: Notify when tags in a rule match the event's tags
|
327
|
+
Given the check is check 'Disk / Util' on entity 'foo-app-01.xyz'
|
328
|
+
And the check is in an ok state
|
329
|
+
When a critical event is received
|
330
|
+
And 1 minute passes
|
331
|
+
And a critical event is received
|
332
|
+
Then 1 sms alert should be queued for +61400000004
|
333
|
+
|
334
|
+
@time
|
335
|
+
Scenario: Don't notify when tags in a rule don't match the event's tags
|
336
|
+
Given the check is check 'Memory Util' on entity 'foo-app-01.xyz'
|
337
|
+
And the check is in an ok state
|
338
|
+
When a critical event is received
|
339
|
+
And 1 minute passes
|
340
|
+
And a critical event is received
|
341
|
+
Then no sms alerts should be queued for +61400000004
|
342
|
+
|
343
|
+
@time
|
344
|
+
Scenario: Only notify during specified time periods in tag matched rules
|
345
|
+
Given the timezone is Europe/Rome
|
346
|
+
And the time is February 1 2013 6:59
|
347
|
+
And the check is check 'ping' on entity 'foo-app-01.xyz'
|
348
|
+
And the check is in an ok state
|
349
|
+
And a critical event is received
|
350
|
+
Then no sms alerts should be queued for +61400000004
|
351
|
+
And the time is February 1 2013 7:01
|
352
|
+
And a critical event is received
|
353
|
+
Then no sms alerts should be queued for +61400000004
|
354
|
+
And the time is February 1 2013 8:01
|
355
|
+
And a critical event is received
|
356
|
+
Then 1 sms alert should be queued for +61400000004
|
357
|
+
When the time is February 1 2013 12:00
|
358
|
+
Then all alert dropping keys for user 1 should have expired
|
359
|
+
When a critical event is received
|
360
|
+
Then 2 sms alerts should be queued for +61400000004
|
361
|
+
When the time is February 1 2013 17:59
|
362
|
+
Then all alert dropping keys for user 1 should have expired
|
363
|
+
When a critical event is received
|
364
|
+
Then 3 sms alerts should be queued for +61400000004
|
365
|
+
When the time is February 1 2013 18:01
|
366
|
+
Then all alert dropping keys for user 1 should have expired
|
367
|
+
When a critical event is received
|
368
|
+
Then 3 sms alerts should be queued for +61400000004
|
369
|
+
|
370
|
+
|
@@ -289,6 +289,15 @@ Then /^show me the (\w+ )*log$/ do |adjective|
|
|
289
289
|
puts @logger.messages.join("\n")
|
290
290
|
end
|
291
291
|
|
292
|
+
Then /^dump notification rules for user (\d+)$/ do |contact|
|
293
|
+
rule_ids = @redis.smembers("contact_notification_rules:#{contact}")
|
294
|
+
puts "There #{(rule_ids.length == 1) ? 'is' : 'are'} #{rule_ids.length} notification rule#{(rule_ids.length == 1) ? '' : 's'} for user #{contact}:"
|
295
|
+
rule_ids.each {|rule_id|
|
296
|
+
rule = Flapjack::Data::NotificationRule.find_by_id(rule_id, :redis => @redis)
|
297
|
+
puts rule.to_json
|
298
|
+
}
|
299
|
+
end
|
300
|
+
|
292
301
|
# added for notification rules:
|
293
302
|
Given /^the following entities exist:$/ do |entities|
|
294
303
|
entities.hashes.each do |entity|
|
@@ -335,7 +344,7 @@ Given /^user (\d+) has the following notification rules:$/ do |contact_id, rules
|
|
335
344
|
end
|
336
345
|
rules.hashes.each do |rule|
|
337
346
|
entities = rule['entities'].split(',').map { |x| x.strip }
|
338
|
-
|
347
|
+
tags = rule['tags'].split(',').map { |x| x.strip }
|
339
348
|
warning_media = rule['warning_media'].split(',').map { |x| x.strip }
|
340
349
|
critical_media = rule['critical_media'].split(',').map { |x| x.strip }
|
341
350
|
warning_blackhole = (rule['warning_blackhole'].downcase == 'true')
|
@@ -352,13 +361,16 @@ Given /^user (\d+) has the following notification rules:$/ do |contact_id, rules
|
|
352
361
|
end
|
353
362
|
rule_data = {:contact_id => contact_id,
|
354
363
|
:entities => entities,
|
355
|
-
:
|
364
|
+
:tags => tags,
|
356
365
|
:warning_media => warning_media,
|
357
366
|
:critical_media => critical_media,
|
358
367
|
:warning_blackhole => warning_blackhole,
|
359
368
|
:critical_blackhole => critical_blackhole,
|
360
369
|
:time_restrictions => time_restrictions}
|
361
|
-
Flapjack::Data::NotificationRule.add(rule_data, :redis => @redis)
|
370
|
+
created_rule = Flapjack::Data::NotificationRule.add(rule_data, :redis => @redis)
|
371
|
+
unless created_rule.is_a?(Flapjack::Data::NotificationRule)
|
372
|
+
raise "Error creating notification rule with data: #{rule_data}, errors: #{created_rule.join(', ')}"
|
373
|
+
end
|
362
374
|
end
|
363
375
|
end
|
364
376
|
|
data/lib/flapjack/coordinator.rb
CHANGED
@@ -28,8 +28,8 @@ module Flapjack
|
|
28
28
|
@boot_time = Time.now
|
29
29
|
|
30
30
|
EM.synchrony do
|
31
|
-
add_pikelets(pikelets(@config.all))
|
32
31
|
setup_signals if options[:signals]
|
32
|
+
add_pikelets(pikelets(@config.all))
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -124,7 +124,7 @@ module Flapjack
|
|
124
124
|
start_piks = []
|
125
125
|
pikelets_data.each_pair do |type, cfg|
|
126
126
|
next unless pikelet = Flapjack::Pikelet.create(type,
|
127
|
-
:config => cfg, :redis_config => @redis_options, :boot_time => @boot_time)
|
127
|
+
:config => cfg, :redis_config => @redis_options, :boot_time => @boot_time, :coordinator => self)
|
128
128
|
start_piks << pikelet
|
129
129
|
@pikelets << pikelet
|
130
130
|
end
|
@@ -132,7 +132,7 @@ module Flapjack
|
|
132
132
|
start_piks.each {|pik| pik.start }
|
133
133
|
rescue Exception => e
|
134
134
|
trace = e.backtrace.join("\n")
|
135
|
-
@logger.fatal "#{e.message}\n#{trace}"
|
135
|
+
@logger.fatal "#{e.class.name}\n#{e.message}\n#{trace}"
|
136
136
|
stop
|
137
137
|
end
|
138
138
|
end
|
@@ -175,7 +175,7 @@ module Flapjack
|
|
175
175
|
if rules.all? {|r| r.is_specific? } # also true if empty
|
176
176
|
rule = self.add_notification_rule({
|
177
177
|
:entities => [],
|
178
|
-
:
|
178
|
+
:tags => Flapjack::Data::TagSet.new([]),
|
179
179
|
:time_restrictions => [],
|
180
180
|
:warning_media => ['email', 'sms', 'jabber', 'pagerduty'],
|
181
181
|
:critical_media => ['email', 'sms', 'jabber', 'pagerduty'],
|
data/lib/flapjack/data/entity.rb
CHANGED
@@ -95,6 +95,17 @@ module Flapjack
|
|
95
95
|
}.sort
|
96
96
|
end
|
97
97
|
|
98
|
+
def self.find_all_with_tags(tags, options = {})
|
99
|
+
raise "Redis connection not set" unless redis = options[:redis]
|
100
|
+
tags_prefixed = tags.collect {|tag|
|
101
|
+
"#{TAG_PREFIX}:#{tag}"
|
102
|
+
}
|
103
|
+
logger.debug "tags_prefixed: #{tags_prefixed.inspect}" if logger = options[:logger]
|
104
|
+
Flapjack::Data::Tag.find_intersection(tags_prefixed, :redis => redis).collect {|entity_id|
|
105
|
+
Flapjack::Data::Entity.find_by_id(entity_id, :redis => redis).name
|
106
|
+
}.compact
|
107
|
+
end
|
108
|
+
|
98
109
|
def self.find_all_with_checks(options)
|
99
110
|
raise "Redis connection not set" unless redis = options[:redis]
|
100
111
|
redis.zrange("current_entities", 0, -1)
|
@@ -119,7 +130,7 @@ module Flapjack
|
|
119
130
|
end
|
120
131
|
|
121
132
|
def check_list
|
122
|
-
@redis.zrange("current_checks:#{@name}", 0, -1)
|
133
|
+
@redis.zrange("current_checks:#{@name}", 0, -1)
|
123
134
|
end
|
124
135
|
|
125
136
|
def check_count
|
@@ -92,14 +92,14 @@ module Flapjack
|
|
92
92
|
memo[entity] ||= []
|
93
93
|
memo[entity] << check
|
94
94
|
end
|
95
|
-
memo
|
95
|
+
memo
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
99
|
def self.count_all_failing(options = {})
|
100
100
|
raise "Redis connection not set" unless redis = options[:redis]
|
101
101
|
redis.zrange("failed_checks", 0, -1).count do |key|
|
102
|
-
entity, check = key.split(':', 2)
|
102
|
+
entity, check = key.split(':', 2)
|
103
103
|
!!redis.zscore("current_checks:#{entity}", check)
|
104
104
|
end
|
105
105
|
end
|
@@ -515,6 +515,13 @@ module Flapjack
|
|
515
515
|
}.compact
|
516
516
|
end
|
517
517
|
|
518
|
+
def tags
|
519
|
+
entity, check = @key.split(":", 2)
|
520
|
+
ta = Flapjack::Data::TagSet.new([])
|
521
|
+
ta += entity.split('.', 2).map {|x| x.downcase}
|
522
|
+
ta += check.split(' ').map {|x| x.downcase}
|
523
|
+
end
|
524
|
+
|
518
525
|
private
|
519
526
|
|
520
527
|
def initialize(entity, check, options = {})
|
data/lib/flapjack/data/event.rb
CHANGED
@@ -6,7 +6,7 @@ module Flapjack
|
|
6
6
|
module Data
|
7
7
|
class Event
|
8
8
|
|
9
|
-
attr_accessor :counter, :previous_state, :previous_state_duration
|
9
|
+
attr_accessor :counter, :previous_state, :previous_state_duration, :tags
|
10
10
|
|
11
11
|
attr_reader :check, :summary, :details, :acknowledgement_id
|
12
12
|
|
@@ -65,14 +65,14 @@ module Flapjack
|
|
65
65
|
raise "Redis connection not set" unless redis = opts[:redis]
|
66
66
|
|
67
67
|
evt['time'] = Time.now.to_i if evt['time'].nil?
|
68
|
-
redis.
|
68
|
+
redis.lpush('events', ::Oj.dump(evt))
|
69
69
|
end
|
70
70
|
|
71
71
|
# Provide a count of the number of events on the queue to be processed.
|
72
|
-
def self.pending_count(opts = {})
|
72
|
+
def self.pending_count(queue, opts = {})
|
73
73
|
raise "Redis connection not set" unless redis = opts[:redis]
|
74
74
|
|
75
|
-
redis.llen(
|
75
|
+
redis.llen(queue)
|
76
76
|
end
|
77
77
|
|
78
78
|
def self.create_acknowledgement(entity_name, check, opts = {})
|
@@ -48,6 +48,7 @@ module Flapjack
|
|
48
48
|
|
49
49
|
last_state = opts[:last_state] || {}
|
50
50
|
|
51
|
+
tag_data = event.tags.is_a?(Set) ? event.tags.to_a : nil
|
51
52
|
notif = {'event_id' => event.id,
|
52
53
|
'state' => event.state,
|
53
54
|
'summary' => event.summary,
|
@@ -58,7 +59,8 @@ module Flapjack
|
|
58
59
|
'duration' => event.duration || nil,
|
59
60
|
'type' => opts[:type] || type_for_event(event),
|
60
61
|
'severity' => opts[:severity],
|
61
|
-
'count' => event.counter
|
62
|
+
'count' => event.counter,
|
63
|
+
'tags' => tag_data }
|
62
64
|
|
63
65
|
redis.rpush(queue, Oj.dump(notif))
|
64
66
|
end
|
@@ -96,7 +98,8 @@ module Flapjack
|
|
96
98
|
'time' => @event_time,
|
97
99
|
'duration' => @event_duration,
|
98
100
|
'notification_type' => @type,
|
99
|
-
'event_count' => @event_count
|
101
|
+
'event_count' => @event_count,
|
102
|
+
'tags' => @tags
|
100
103
|
}
|
101
104
|
end
|
102
105
|
|
@@ -111,35 +114,39 @@ module Flapjack
|
|
111
114
|
rules = contact.notification_rules
|
112
115
|
media = contact.media
|
113
116
|
|
114
|
-
logger.debug "
|
117
|
+
logger.debug "Notification#messages: creating messages for contact: #{contact_id} " +
|
118
|
+
"event_id: \"#{@event_id}\" state: #{@event_state} event_tags: #{@tags.to_json} media: #{media.inspect}"
|
115
119
|
rlen = rules.length
|
116
|
-
logger.debug "found #{rlen} rule#{(rlen == 1) ? '' : 's'} for contact"
|
120
|
+
logger.debug "found #{rlen} rule#{(rlen == 1) ? '' : 's'} for contact #{contact_id}"
|
117
121
|
|
118
122
|
media_to_use = if rules.empty?
|
119
123
|
media
|
120
124
|
else
|
121
125
|
# matchers are rules of the contact that have matched the current event
|
122
|
-
# for time and
|
126
|
+
# for time, entity and tags
|
123
127
|
matchers = rules.select do |rule|
|
124
|
-
rule.
|
128
|
+
logger.debug("considering rule with entities: #{rule.entities} and tags: #{rule.tags.to_json}")
|
129
|
+
(rule.match_entity?(@event_id) || rule.match_tags?(@tags) || ! rule.is_specific?) &&
|
125
130
|
rule_occurring_now?(rule, :contact => contact, :default_timezone => default_timezone)
|
126
131
|
end
|
127
132
|
|
128
|
-
logger.debug "#{matchers.length} matchers remain for this contact:"
|
133
|
+
logger.debug "#{matchers.length} matchers remain for this contact after time, entity and tags are matched:"
|
129
134
|
matchers.each do |matcher|
|
130
135
|
logger.debug "matcher: #{matcher.to_json}"
|
131
136
|
end
|
132
137
|
|
133
|
-
# delete any matchers
|
138
|
+
# delete any general matchers if there are more specific matchers left
|
134
139
|
if matchers.any? {|matcher| matcher.is_specific? }
|
135
140
|
|
136
|
-
logger.debug("general removal: found #{matchers.length} entity specific matchers")
|
137
141
|
num_matchers = matchers.length
|
138
142
|
|
139
143
|
matchers.reject! {|matcher| !matcher.is_specific? }
|
140
144
|
|
141
145
|
if num_matchers != matchers.length
|
142
146
|
logger.debug("notification: removal of general matchers when entity specific matchers are present: number of matchers changed from #{num_matchers} to #{matchers.length} for contact id: #{contact_id}")
|
147
|
+
matchers.each do |matcher|
|
148
|
+
logger.debug "matcher: #{matcher.to_json}"
|
149
|
+
end
|
143
150
|
end
|
144
151
|
end
|
145
152
|
|
@@ -179,19 +186,19 @@ module Flapjack
|
|
179
186
|
|
180
187
|
# created from parsed JSON, so opts keys are in strings
|
181
188
|
def initialize(opts = {})
|
182
|
-
@event_id
|
183
|
-
@event_state
|
184
|
-
@event_summary
|
185
|
-
@event_details
|
186
|
-
@event_time
|
187
|
-
@event_duration
|
188
|
-
@event_count
|
189
|
-
|
189
|
+
@event_id = opts['event_id']
|
190
|
+
@event_state = opts['state']
|
191
|
+
@event_summary = opts['summary']
|
192
|
+
@event_details = opts['details']
|
193
|
+
@event_time = opts['time']
|
194
|
+
@event_duration = opts['duration']
|
195
|
+
@event_count = opts['count']
|
190
196
|
@last_event_state = opts['last_state']
|
191
197
|
@last_event_summary = opts['last_summary']
|
192
|
-
|
193
|
-
@
|
194
|
-
|
198
|
+
@type = opts['type']
|
199
|
+
@severity = opts['severity']
|
200
|
+
tags = opts['tags']
|
201
|
+
@tags = tags.is_a?(Array) ? Flapjack::Data::TagSet.new(tags) : nil
|
195
202
|
end
|
196
203
|
|
197
204
|
# # time restrictions match?
|