flapjack 0.7.28 → 0.7.29
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +10 -0
- data/features/notification_rules.feature +25 -25
- data/features/rollup.feature +38 -18
- data/features/steps/events_steps.rb +10 -5
- data/features/steps/notifications_steps.rb +8 -4
- data/lib/flapjack/data/alert.rb +207 -0
- data/lib/flapjack/data/contact.rb +14 -7
- data/lib/flapjack/data/entity_check.rb +4 -3
- data/lib/flapjack/data/notification.rb +28 -27
- data/lib/flapjack/gateways/api/contact_methods.rb +32 -12
- data/lib/flapjack/gateways/email.rb +49 -53
- data/lib/flapjack/gateways/email/alert.html.erb +15 -15
- data/lib/flapjack/gateways/email/alert.text.erb +15 -15
- data/lib/flapjack/gateways/email/alert_subject.text.erb +3 -13
- data/lib/flapjack/gateways/email/rollup.html.erb +6 -6
- data/lib/flapjack/gateways/email/rollup.text.erb +7 -7
- data/lib/flapjack/gateways/email/rollup_subject.text.erb +1 -19
- data/lib/flapjack/gateways/jabber.rb +57 -47
- data/lib/flapjack/gateways/jabber/alert.text.erb +12 -0
- data/lib/flapjack/gateways/jabber/rollup.text.erb +2 -0
- data/lib/flapjack/gateways/pagerduty.rb +60 -30
- data/lib/flapjack/gateways/pagerduty/alert.text.erb +10 -0
- data/lib/flapjack/gateways/sms_messagenet.rb +29 -36
- data/lib/flapjack/gateways/sms_messagenet/alert.text.erb +4 -14
- data/lib/flapjack/gateways/sms_messagenet/rollup.text.erb +2 -34
- data/lib/flapjack/gateways/web.rb +23 -14
- data/lib/flapjack/gateways/web/views/check.html.erb +16 -11
- data/lib/flapjack/gateways/web/views/contact.html.erb +58 -16
- data/lib/flapjack/gateways/web/views/self_stats.html.erb +80 -71
- data/lib/flapjack/notifier.rb +8 -2
- data/lib/flapjack/pikelet.rb +17 -3
- data/lib/flapjack/processor.rb +0 -1
- data/lib/flapjack/redis_pool.rb +1 -1
- data/lib/flapjack/utility.rb +13 -0
- data/lib/flapjack/version.rb +1 -1
- data/spec/lib/flapjack/data/contact_spec.rb +44 -29
- data/spec/lib/flapjack/gateways/api/contact_methods_spec.rb +24 -4
- data/spec/lib/flapjack/gateways/email_spec.rb +0 -5
- data/spec/lib/flapjack/gateways/jabber_spec.rb +5 -1
- data/spec/lib/flapjack/gateways/pagerduty_spec.rb +5 -2
- data/spec/lib/flapjack/gateways/{sms_messagenet.spec.rb → sms_messagenet_spec.rb} +16 -12
- data/spec/lib/flapjack/gateways/web_spec.rb +1 -1
- data/spec/spec_helper.rb +28 -6
- metadata +43 -89
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a8a6bbb199b138fb0da3af9765f5f0fe7b2ad552
|
4
|
+
data.tar.gz: 3dbd00e9e7e63978726cb0f1e78fc96639f1762b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 981b9061652d0a75e5e32cb82590c20eeca4a7b2d624aad076097c8a39c799a0850110e67fe080afa6ffac5dbe16d39184d06014db3d3cdbf1c469353425019f
|
7
|
+
data.tar.gz: cad93481bc1dfd36c636ea84a0e7d59a9e5b1c926e046cf15b35a58cf4d4d06545bdd600b0cfe4d3e343ab6298944b40efc6ea89747355da04c456db56f46058
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
## Flapjack Changelog
|
2
2
|
|
3
|
+
# 0.7.29 - 2013-11-01
|
4
|
+
- Feature: Per contact media rollup complete gh-291 (@jessereynolds)
|
5
|
+
- Feature: Rollup - show alerting checks and rollup status for each media on contact page gh-326 (@jessereynolds)
|
6
|
+
- Feature: Make message templating more flexible and consistent gh-329 (@jessereynolds)
|
7
|
+
- Feature: Remove misleading internal metrics gh-344 (@jessereynolds)
|
8
|
+
- Bug: clear up pagerduty details API code gh-338 (@ali-graham)
|
9
|
+
- Bug: non-numeric contact ID not properly supported - thanks @avishai-ish-shalom gh-338 (@jessereynolds)
|
10
|
+
- Bug: GET /contacts gives you more than you bargained for gh-339 (@jessereynolds)
|
11
|
+
- Bug: SMS alerts being sent from separate environment gh-135 (@jessereynolds)
|
12
|
+
|
3
13
|
# 0.7.28 - 2013-10-21
|
4
14
|
- Feature: Per contact media rollup (summary) notifications - foundation (data, api, web UI etc) gh-291 (@jessereynolds)
|
5
15
|
- Feature: flapper takes an IP to bind to gh-98 (@ali-graham)
|
@@ -4,51 +4,51 @@ Feature: Notification rules on a per contact basis
|
|
4
4
|
Background:
|
5
5
|
Given the following users exist:
|
6
6
|
| id | first_name | last_name | email | sms | timezone |
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
| c1 | Malak | Al-Musawi | malak@example.com | +61400000001 | Asia/Baghdad |
|
8
|
+
| c2 | Imani | Farooq | imani@example.com | +61400000002 | Europe/Moscow |
|
9
|
+
| c3 | Vera | Дурейко | vera@example.com | +61400000003 | Europe/Paris |
|
10
|
+
| c4 | Lucia | Moretti | lucia@example.com | +61400000004 | Europe/Rome |
|
11
|
+
| c5 | Wang Fang | Wong | fang@example.com | +61400000005 | Asia/Shanghai |
|
12
12
|
|
13
13
|
And the following entities exist:
|
14
14
|
| id | name | contacts |
|
15
|
-
| 1 | foo |
|
16
|
-
| 2 | bar |
|
17
|
-
| 3 | baz |
|
18
|
-
| 4 | buf |
|
19
|
-
| 5 | foo-app-01.xyz |
|
15
|
+
| 1 | foo | c1 |
|
16
|
+
| 2 | bar | c1,c2,c3 |
|
17
|
+
| 3 | baz | c1,c3 |
|
18
|
+
| 4 | buf | c1,c2,c3 |
|
19
|
+
| 5 | foo-app-01.xyz | c4 |
|
20
20
|
|
21
|
-
And user
|
21
|
+
And user c1 has the following notification intervals:
|
22
22
|
| email | sms |
|
23
23
|
| 15 | 60 |
|
24
24
|
|
25
|
-
And user
|
25
|
+
And user c2 has the following notification intervals:
|
26
26
|
| email | sms |
|
27
27
|
| 15 | 60 |
|
28
28
|
|
29
|
-
And user
|
29
|
+
And user c3 has the following notification intervals:
|
30
30
|
| email | sms |
|
31
31
|
| 15 | 60 |
|
32
32
|
|
33
|
-
And user
|
33
|
+
And user c4 has the following notification intervals:
|
34
34
|
| email | sms |
|
35
35
|
| 15 | 60 |
|
36
36
|
|
37
|
-
And user
|
37
|
+
And user c1 has the following notification rules:
|
38
38
|
| entities | unknown_media | warning_media | critical_media | warning_blackhole | critical_blackhole | time_restrictions |
|
39
39
|
| | | email | sms,email | true | true | |
|
40
40
|
| foo | | email | sms,email | | | 8-18 weekdays |
|
41
41
|
| bar | email | | sms,email | true | | |
|
42
42
|
| baz | | email | sms,email | | | |
|
43
43
|
|
44
|
-
And user
|
44
|
+
And user c2 has the following notification rules:
|
45
45
|
| entities | tags | warning_media | critical_media | warning_blackhole | critical_blackhole |
|
46
46
|
| | | email | email | | |
|
47
47
|
| | | sms | sms | | |
|
48
48
|
| bar | | email | email,sms | | |
|
49
49
|
| bar | wags | | | true | true |
|
50
50
|
|
51
|
-
And user
|
51
|
+
And user c3 has the following notification rules:
|
52
52
|
| entities | warning_media | critical_media | warning_blackhole | critical_blackhole |
|
53
53
|
| | email | email | | |
|
54
54
|
| baz | sms | sms | | |
|
@@ -56,13 +56,13 @@ Feature: Notification rules on a per contact basis
|
|
56
56
|
| buf | sms | sms | | |
|
57
57
|
| bar | email | email | true | true |
|
58
58
|
|
59
|
-
And user
|
59
|
+
And user c4 has the following notification rules:
|
60
60
|
| tags | warning_media | critical_media | time_restrictions |
|
61
61
|
| | | | |
|
62
62
|
| xyz, disk, util | sms | sms | |
|
63
63
|
| xyz, ping | sms,email | sms,email | 8-18 weekdays |
|
64
64
|
|
65
|
-
And user
|
65
|
+
And user c5 has the following notification rules:
|
66
66
|
| unknown_media | critical_media |
|
67
67
|
| email | email, sms |
|
68
68
|
|
@@ -81,15 +81,15 @@ Feature: Notification rules on a per contact basis
|
|
81
81
|
And a critical event is received
|
82
82
|
Then 1 email alert should be queued for malak@example.com
|
83
83
|
When the time is February 1 2013 12:00
|
84
|
-
Then all alert dropping keys for user
|
84
|
+
Then all alert dropping keys for user c1 should have expired
|
85
85
|
When a critical event is received
|
86
86
|
Then 2 email alerts should be queued for malak@example.com
|
87
87
|
When the time is February 1 2013 17:59
|
88
|
-
Then all alert dropping keys for user
|
88
|
+
Then all alert dropping keys for user c1 should have expired
|
89
89
|
When a critical event is received
|
90
90
|
Then 3 email alerts should be queued for malak@example.com
|
91
91
|
When the time is February 1 2013 18:01
|
92
|
-
Then all alert dropping keys for user
|
92
|
+
Then all alert dropping keys for user c1 should have expired
|
93
93
|
When a critical event is received
|
94
94
|
Then 3 email alerts should be queued for malak@example.com
|
95
95
|
|
@@ -395,15 +395,15 @@ Feature: Notification rules on a per contact basis
|
|
395
395
|
And a critical event is received
|
396
396
|
Then 1 sms alert should be queued for +61400000004
|
397
397
|
When the time is February 1 2013 12:00
|
398
|
-
Then all alert dropping keys for user
|
398
|
+
Then all alert dropping keys for user c1 should have expired
|
399
399
|
When a critical event is received
|
400
400
|
Then 2 sms alerts should be queued for +61400000004
|
401
401
|
When the time is February 1 2013 17:59
|
402
|
-
Then all alert dropping keys for user
|
402
|
+
Then all alert dropping keys for user c1 should have expired
|
403
403
|
When a critical event is received
|
404
404
|
Then 3 sms alerts should be queued for +61400000004
|
405
405
|
When the time is February 1 2013 18:01
|
406
|
-
Then all alert dropping keys for user
|
406
|
+
Then all alert dropping keys for user c1 should have expired
|
407
407
|
When a critical event is received
|
408
408
|
Then 3 sms alerts should be queued for +61400000004
|
409
409
|
|
data/features/rollup.feature
CHANGED
@@ -177,22 +177,42 @@ Feature: Rollup on a per contact, per media basis
|
|
177
177
|
Then 1 sms alert of type problem and rollup problem should be queued for +61400000001
|
178
178
|
And 2 sms alerts should be queued for +61400000001
|
179
179
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
180
|
+
@time
|
181
|
+
Scenario: Contact ceases to be a contact on an entity that they were being alerted for
|
182
|
+
Given check 'ping' for entity 'foo' is in an ok state
|
183
|
+
And check 'ping' for entity 'baz' is in an ok state
|
184
|
+
When a critical event is received for check 'ping' on entity 'foo'
|
185
|
+
And 1 minute passes
|
186
|
+
And a critical event is received for check 'ping' on entity 'foo'
|
187
|
+
Then 1 sms alerts of type problem and rollup none should be queued for +61400000001
|
188
|
+
When 5 minutes passes
|
189
|
+
And a critical event is received for check 'ping' on entity 'baz'
|
190
|
+
And 1 minute passes
|
191
|
+
And a critical event is received for check 'ping' on entity 'baz'
|
192
|
+
Then 1 sms alert of type problem and rollup problem should be queued for +61400000001
|
193
|
+
And 1 sms alerts of type problem and rollup none should be queued for +61400000001
|
194
|
+
And 2 sms alerts should be queued for +61400000001
|
195
|
+
When 20 minute passes
|
196
|
+
And user 1 ceases to be a contact of entity 'foo'
|
197
|
+
And a critical event is received for check 'ping' on entity 'baz'
|
198
|
+
Then 1 sms alert of rollup recovery should be queued for +61400000001
|
199
|
+
|
200
|
+
@time
|
201
|
+
Scenario: Test notification to not contribute to rollup
|
202
|
+
Given check 'ping' for entity 'foo' is in an ok state
|
203
|
+
And check 'ping' for entity 'baz' is in an ok state
|
204
|
+
When a critical event is received for check 'ping' on entity 'foo'
|
205
|
+
And 1 minute passes
|
206
|
+
And a critical event is received for check 'ping' on entity 'foo'
|
207
|
+
Then 1 sms alert of type problem and rollup none should be queued for +61400000001
|
208
|
+
And 1 sms alert should be queued for +61400000001
|
209
|
+
When 1 minute passes
|
210
|
+
And a test event is received for check 'sausage' on entity 'foo'
|
211
|
+
Then 1 sms alert of type problem and rollup none should be queued for +61400000001
|
212
|
+
And 1 sms alert of type test and rollup none should be queued for +61400000001
|
213
|
+
And 2 sms alerts should be queued for +61400000001
|
214
|
+
When 20 minutes passes
|
215
|
+
And a critical event is received for check 'ping' on entity 'foo'
|
216
|
+
Then 2 sms alerts of type problem and rollup none should be queued for +61400000001
|
217
|
+
And 3 sms alerts should be queued for +61400000001
|
198
218
|
|
@@ -301,7 +301,7 @@ Then /^show me the (\w+ )*log$/ do |adjective|
|
|
301
301
|
puts @logger.messages.join("\n")
|
302
302
|
end
|
303
303
|
|
304
|
-
Then /^dump notification rules for user (\
|
304
|
+
Then /^dump notification rules for user (\S+)$/ do |contact|
|
305
305
|
rule_ids = @redis.smembers("contact_notification_rules:#{contact}")
|
306
306
|
puts "There #{(rule_ids.length == 1) ? 'is' : 'are'} #{rule_ids.length} notification rule#{(rule_ids.length == 1) ? '' : 's'} for user #{contact}:"
|
307
307
|
rule_ids.each {|rule_id|
|
@@ -338,7 +338,7 @@ Given /^the following users exist:$/ do |contacts|
|
|
338
338
|
end
|
339
339
|
end
|
340
340
|
|
341
|
-
Given /^user (\
|
341
|
+
Given /^user (\S+) has the following notification intervals:$/ do |contact_id, intervals|
|
342
342
|
contact = Flapjack::Data::Contact.find_by_id(contact_id, :redis => @redis)
|
343
343
|
intervals.hashes.each do |interval|
|
344
344
|
contact.set_interval_for_media('email', interval['email'].to_i * 60)
|
@@ -346,7 +346,7 @@ Given /^user (\d+) has the following notification intervals:$/ do |contact_id, i
|
|
346
346
|
end
|
347
347
|
end
|
348
348
|
|
349
|
-
Given /^user (\
|
349
|
+
Given /^user (\S+) has the following notification rollup thresholds:$/ do |contact_id, rollup_thresholds|
|
350
350
|
contact = Flapjack::Data::Contact.find_by_id(contact_id, :redis => @redis)
|
351
351
|
rollup_thresholds.hashes.each do |rollup_threshold|
|
352
352
|
contact.set_rollup_threshold_for_media('email', rollup_threshold['email'].to_i)
|
@@ -354,7 +354,7 @@ Given /^user (\d+) has the following notification rollup thresholds:$/ do |conta
|
|
354
354
|
end
|
355
355
|
end
|
356
356
|
|
357
|
-
Given /^user (\
|
357
|
+
Given /^user (\S+) has the following notification rules:$/ do |contact_id, rules|
|
358
358
|
contact = Flapjack::Data::Contact.find_by_id(contact_id, :redis => @redis)
|
359
359
|
timezone = contact.timezone
|
360
360
|
|
@@ -400,7 +400,7 @@ Given /^user (\d+) has the following notification rules:$/ do |contact_id, rules
|
|
400
400
|
end
|
401
401
|
end
|
402
402
|
|
403
|
-
Then /^all alert dropping keys for user (\
|
403
|
+
Then /^all alert dropping keys for user (\S+) should have expired$/ do |contact_id|
|
404
404
|
@redis.keys("drop_alerts_for_contact:#{contact_id}*").should be_empty
|
405
405
|
end
|
406
406
|
|
@@ -426,3 +426,8 @@ Then /^(\w+) (\w+) alert(?:s)?(?: of)?(?: type (\w+))?(?: and)?(?: rollup (\w+))
|
|
426
426
|
}.length.should == num_queued.to_i
|
427
427
|
end
|
428
428
|
|
429
|
+
When(/^user (\S+) ceases to be a contact of entity '(.*)'$/) do |contact_id, entity|
|
430
|
+
entity = Flapjack::Data::Entity.find_by_name(entity, :redis => @redis)
|
431
|
+
@redis.srem("contacts_for:#{entity.id}", contact_id)
|
432
|
+
end
|
433
|
+
|
@@ -109,12 +109,14 @@ Given /^a user SMS notification has been queued for entity '([\w\.\-]+)'$/ do |e
|
|
109
109
|
@sms_notification = {'notification_type' => 'problem',
|
110
110
|
'contact_first_name' => 'John',
|
111
111
|
'contact_last_name' => 'Smith',
|
112
|
-
'state' => '
|
112
|
+
'state' => 'critical',
|
113
113
|
'summary' => 'Socket timeout after 10 seconds',
|
114
114
|
'time' => Time.now.to_i,
|
115
115
|
'event_id' => "#{entity}:ping",
|
116
116
|
'address' => '+61412345678',
|
117
|
-
'id' => 1
|
117
|
+
'id' => 1,
|
118
|
+
'state_duration' => 30,
|
119
|
+
'duration' => 45}
|
118
120
|
end
|
119
121
|
|
120
122
|
Given /^a user email notification has been queued for entity '([\w\.\-]+)'$/ do |entity|
|
@@ -124,12 +126,14 @@ Given /^a user email notification has been queued for entity '([\w\.\-]+)'$/ do
|
|
124
126
|
@email_notification = {'notification_type' => 'problem',
|
125
127
|
'contact_first_name' => 'John',
|
126
128
|
'contact_last_name' => 'Smith',
|
127
|
-
'state' => '
|
129
|
+
'state' => 'critical',
|
128
130
|
'summary' => 'Socket timeout after 10 seconds',
|
129
131
|
'time' => Time.now.to_i,
|
130
132
|
'event_id' => "#{entity}:ping",
|
131
133
|
'address' => 'johns@example.dom',
|
132
|
-
'id' => 2
|
134
|
+
'id' => 2,
|
135
|
+
'state_duration' => 30,
|
136
|
+
'duration' => 3600}
|
133
137
|
end
|
134
138
|
|
135
139
|
# NB using perform, the notifiers were accessing the wrong Redis DB number
|
@@ -0,0 +1,207 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'active_support/inflector'
|
4
|
+
require 'flapjack/utility'
|
5
|
+
|
6
|
+
# Alert is the object ready to send to someone, complete with an address and all
|
7
|
+
# the data with which to render the text of the alert in the appropriate gateway
|
8
|
+
#
|
9
|
+
# It should possibly be renamed AlertPresenter
|
10
|
+
|
11
|
+
module Flapjack
|
12
|
+
module Data
|
13
|
+
class Alert
|
14
|
+
|
15
|
+
# from Flapjack::Data::Notification
|
16
|
+
attr_reader :event_id,
|
17
|
+
:state,
|
18
|
+
:summary,
|
19
|
+
:acknowledgement_duration,
|
20
|
+
:last_state,
|
21
|
+
:last_summary,
|
22
|
+
:state_duration,
|
23
|
+
:details,
|
24
|
+
:time,
|
25
|
+
:notification_type,
|
26
|
+
:event_count,
|
27
|
+
:tags
|
28
|
+
|
29
|
+
# from Flapjack::Data::Message
|
30
|
+
# :id,
|
31
|
+
attr_reader :media,
|
32
|
+
:address,
|
33
|
+
:rollup,
|
34
|
+
:contact_id,
|
35
|
+
:contact_first_name,
|
36
|
+
:contact_last_name
|
37
|
+
|
38
|
+
# from Flapjack::Notifier
|
39
|
+
attr_reader :rollup_threshold,
|
40
|
+
:rollup_alerts,
|
41
|
+
:in_scheduled_maintenance,
|
42
|
+
:in_unscheduled_maintenance
|
43
|
+
|
44
|
+
# from self
|
45
|
+
attr_reader :entity,
|
46
|
+
:check,
|
47
|
+
:notification_id
|
48
|
+
|
49
|
+
include Flapjack::Utility
|
50
|
+
|
51
|
+
def initialize(contents, opts)
|
52
|
+
raise "no logger supplied" unless @logger = opts[:logger]
|
53
|
+
|
54
|
+
@event_id = contents['event_id']
|
55
|
+
@state = contents['state']
|
56
|
+
@summary = contents['summary']
|
57
|
+
@acknowledgement_duration = contents['duration'] # SMELLY
|
58
|
+
@last_state = contents['last_state']
|
59
|
+
@last_summary = contents['last_summary']
|
60
|
+
@state_duration = contents['state_duration']
|
61
|
+
@details = contents['details']
|
62
|
+
@time = contents['time']
|
63
|
+
@notification_type = contents['notification_type']
|
64
|
+
@event_count = contents['event_count']
|
65
|
+
@tags = contents['tags']
|
66
|
+
|
67
|
+
@media = contents['media']
|
68
|
+
@address = contents['address']
|
69
|
+
@rollup = contents['rollup']
|
70
|
+
@contact_id = contents['contact_id']
|
71
|
+
@contact_first_name = contents['contact_first_name']
|
72
|
+
@contact_last_name = contents['contact_last_name']
|
73
|
+
|
74
|
+
@rollup_threshold = contents['rollup_threshold']
|
75
|
+
@rollup_alerts = contents['rollup_alerts']
|
76
|
+
@in_scheduled_maintenance = contents['in_scheduled_maintenance']
|
77
|
+
@in_unscheduled_maintenance = contents['in_unscheduled_maintenance']
|
78
|
+
|
79
|
+
@entity, @check = @event_id.split(':', 2)
|
80
|
+
@notification_id = contents['id'] || SecureRandom.uuid
|
81
|
+
|
82
|
+
allowed_states = ['ok', 'critical', 'warning', 'unknown', 'test_notifications', 'acknowledgement']
|
83
|
+
allowed_rollup_states = ['critical', 'warning', 'unknown']
|
84
|
+
raise "state #{@state.inspect} is invalid" unless
|
85
|
+
allowed_states.include?(@state)
|
86
|
+
|
87
|
+
raise "state_duration #{@state_duration.inspect} is invalid" unless
|
88
|
+
@state_duration && @state_duration.is_a?(Integer) && @state_duration >= 0
|
89
|
+
|
90
|
+
if @rollup_alerts
|
91
|
+
raise "rollup_alerts should be nil or a hash" unless @rollup_alerts.is_a?(Hash)
|
92
|
+
@rollup_alerts.each_pair do |check, details|
|
93
|
+
raise "duration of rollup_alerts['#{check}'] must be an integer" unless
|
94
|
+
details['duration'] && details['duration'].is_a?(Integer)
|
95
|
+
raise "state of rollup_alerts['#{check}'] is invalid" unless
|
96
|
+
details['state'] && allowed_rollup_states.include?(details['state'])
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
def type
|
103
|
+
case @rollup
|
104
|
+
when "problem"
|
105
|
+
"rollup_problem"
|
106
|
+
when "recovery"
|
107
|
+
"rollup_recovery"
|
108
|
+
else
|
109
|
+
@notification_type
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def type_sentence_case
|
114
|
+
case type
|
115
|
+
when "rollup_problem"
|
116
|
+
"Problem summary"
|
117
|
+
when "rollup_recovery"
|
118
|
+
"Problem summaries finishing"
|
119
|
+
else
|
120
|
+
type.titleize
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def state_title_case
|
125
|
+
['ok'].include?(@state) ? @state.upcase : @state.titleize
|
126
|
+
end
|
127
|
+
|
128
|
+
def last_state_title_case
|
129
|
+
['ok'].include?(@last_state) ? @last_state.upcase : @last_state.titleize
|
130
|
+
end
|
131
|
+
|
132
|
+
def rollup_alerts_by_state
|
133
|
+
['critical', 'warning', 'unknown'].inject({}) do |memo, state|
|
134
|
+
alerts = rollup_alerts.find_all {|alert| alert[1]['state'] == state}
|
135
|
+
memo[state] = alerts
|
136
|
+
memo
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def rollup_state_counts
|
141
|
+
rollup_alerts.inject({}) do |memo, alert|
|
142
|
+
memo[alert[1]['state']] = (memo[alert[1]['state']] || 0) + 1
|
143
|
+
memo
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def rollup_states_summary
|
148
|
+
state_counts = rollup_state_counts
|
149
|
+
['critical', 'warning', 'unknown'].inject([]) do |memo, state|
|
150
|
+
next memo unless rollup_state_counts[state]
|
151
|
+
memo << "#{state.titleize}: #{state_counts[state]}"
|
152
|
+
memo
|
153
|
+
end.join(', ')
|
154
|
+
end
|
155
|
+
|
156
|
+
# produces a textual list of checks that are failing broken down by state, eg:
|
157
|
+
# Critical: 'PING' on 'foo-app-01.example.com', 'SSH' on 'foo-app-01.example.com';
|
158
|
+
# Warning: 'Disk / Utilisation' on 'foo-app-02.example.com'
|
159
|
+
def rollup_states_detail_text(opts)
|
160
|
+
max_checks = opts[:max_checks_per_state]
|
161
|
+
rollup_alerts_by_state.inject([]) do |memo, state|
|
162
|
+
state_titleized = state[0].titleize
|
163
|
+
alerts = max_checks && max_checks > 0 ? state[1][0..(max_checks - 1)] : state[1]
|
164
|
+
next memo if alerts.empty?
|
165
|
+
checks = alerts.map {|alert| alert[0]}
|
166
|
+
checks << '...' if checks.length < rollup_state_counts[state[0]]
|
167
|
+
memo << "#{state[0].titleize}: #{checks.join(', ')}"
|
168
|
+
memo
|
169
|
+
end.join('; ')
|
170
|
+
end
|
171
|
+
|
172
|
+
def to_s
|
173
|
+
msg = "Alert via #{media}:#{address} to contact #{contact_id} (#{contact_first_name} #{contact_last_name}): "
|
174
|
+
msg += type_sentence_case
|
175
|
+
if rollup
|
176
|
+
msg += " - #{rollup_states_summary} (#{rollup_states_detail_text(:max_checks_per_state => 3)})"
|
177
|
+
else
|
178
|
+
msg += " - '#{check}' on #{entity}"
|
179
|
+
unless ['acknowledgement', 'test'].include?(type)
|
180
|
+
msg += " is #{state_title_case}"
|
181
|
+
end
|
182
|
+
if ['acknowledgement'].include?(type)
|
183
|
+
msg += " has been acknowledged, unscheduled maintenance created for "
|
184
|
+
msg += time_period_in_words(acknowledgement_duration)
|
185
|
+
end
|
186
|
+
if summary && summary.length > 0
|
187
|
+
msg += " - #{summary}"
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def record_send_success!
|
193
|
+
@logger.info "Sent alert successfully: #{to_s}"
|
194
|
+
end
|
195
|
+
|
196
|
+
# TODO: perhaps move message send failure porting to this method
|
197
|
+
# to avoid duplication in the gateways, and to more easily allow
|
198
|
+
# better error reporting on message generation / send failure
|
199
|
+
#def record_send_failure!(opts)
|
200
|
+
# exception = opts[:exception]
|
201
|
+
# message = opts[:message]
|
202
|
+
# @logger.error "Error sending an alert! #{alert}"
|
203
|
+
#end
|
204
|
+
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|