flapjack 0.7.20 → 0.7.21
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/.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?
|