flapjack 0.7.28 → 0.7.29
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,25 +1,25 @@
|
|
1
|
-
Hi <%= @contact_first_name %>
|
1
|
+
Hi <%= @alert.contact_first_name %>
|
2
2
|
|
3
3
|
Monitoring has detected the following:
|
4
4
|
|
5
|
-
Entity: <%= @
|
6
|
-
Check: <%= @check %>
|
7
|
-
State: <%=
|
8
|
-
Summary: <%= @summary %>
|
9
|
-
<% if @details -%>
|
10
|
-
Details: <%= @details %>
|
5
|
+
Entity: <%= @alert.entity %>
|
6
|
+
Check: <%= @alert.check %>
|
7
|
+
State: <%= @alert.state_title_case %>
|
8
|
+
Summary: <%= @alert.summary %>
|
9
|
+
<% if @alert.details -%>
|
10
|
+
Details: <%= @alert.details %>
|
11
11
|
<% end -%>
|
12
|
-
<% if @time -%>
|
13
|
-
Time: <%= Time.at(@time.to_i).to_s %>
|
12
|
+
<% if @alert.time -%>
|
13
|
+
Time: <%= Time.at(@alert.time.to_i).to_s %>
|
14
14
|
<% end -%>
|
15
|
-
<% if @
|
16
|
-
Duration: <%= ChronicDuration.output(@
|
15
|
+
<% if @alert.state_duration && @alert.state_duration > 40 -%>
|
16
|
+
Duration: <%= ChronicDuration.output(@alert.state_duration) %>
|
17
17
|
<% end -%>
|
18
|
-
<% if @last_state -%>
|
19
|
-
Previous State: <%=
|
18
|
+
<% if @alert.last_state -%>
|
19
|
+
Previous State: <%= @alert.last_state_title_case %>
|
20
20
|
<% end -%>
|
21
|
-
<% if @last_summary -%>
|
22
|
-
Previous Summary: <%= @last_summary %>
|
21
|
+
<% if @alert.last_summary -%>
|
22
|
+
Previous Summary: <%= @alert.last_summary %>
|
23
23
|
<% end -%>
|
24
24
|
|
25
25
|
Cheers,
|
@@ -1,14 +1,4 @@
|
|
1
|
-
|
2
|
-
<%
|
3
|
-
<%=
|
4
|
-
<% when "recovery" -%>
|
5
|
-
<%= "Recovery: " -%>
|
6
|
-
<% when "acknowledgement" -%>
|
7
|
-
<%= "Acknowledgement: " -%>
|
8
|
-
<% when "test" -%>
|
9
|
-
<%= "Test notification: " -%>
|
10
|
-
<% end -%>
|
11
|
-
'<%= @check %>' on <%= @entity_name -%>
|
12
|
-
<% if ! ['acknowledgement', 'test'].include?(@notification_type) -%>
|
13
|
-
is <%= ['ok'].include?(@state) ? @state.upcase : @state.titleize -%>
|
1
|
+
<%= @alert.type_sentence_case %>: '<%= @alert.check %>' on <%= @alert.entity -%>
|
2
|
+
<% unless ['acknowledgement', 'test'].include?(@alert.notification_type) -%>
|
3
|
+
is <%= @alert.state_title_case -%>
|
14
4
|
<% end -%>
|
@@ -11,9 +11,9 @@
|
|
11
11
|
}
|
12
12
|
</style>
|
13
13
|
|
14
|
-
<p>Hi <%= @contact_first_name %></p>
|
14
|
+
<p>Hi <%= @alert.contact_first_name %></p>
|
15
15
|
|
16
|
-
<p>You have <%= @rollup_alerts.length %> alerting check<%= @rollup_alerts.length == 1 ? '' : 's' %> as follows:</p>
|
16
|
+
<p>You have <%= @alert.rollup_alerts.length %> alerting check<%= @alert.rollup_alerts.length == 1 ? '' : 's' %> as follows:</p>
|
17
17
|
|
18
18
|
<table>
|
19
19
|
<tbody>
|
@@ -23,7 +23,7 @@
|
|
23
23
|
<th>State</th>
|
24
24
|
<th>Duration</th>
|
25
25
|
</tr>
|
26
|
-
<% @rollup_alerts.sort_by {|entity_check, details| details['duration'] }.each do |rollup_alert| -%>
|
26
|
+
<% @alert.rollup_alerts.sort_by {|entity_check, details| details['duration'] }.each do |rollup_alert| -%>
|
27
27
|
<% r_entity, r_check = rollup_alert[0].split(':', 2) -%>
|
28
28
|
<% state = rollup_alert[1]['state'] -%>
|
29
29
|
<% duration = ChronicDuration.output(rollup_alert[1]['duration']) -%>
|
@@ -37,10 +37,10 @@
|
|
37
37
|
</tbody>
|
38
38
|
</table>
|
39
39
|
|
40
|
-
<% if @rollup
|
41
|
-
<p>As your email summary threshold is <%= @rollup_threshold %>, we're taking your email alerts out of summary mode now. You'll now be emailed individually for each alerting check.</p>
|
40
|
+
<% if @alert.rollup == 'recovery' %>
|
41
|
+
<p>As your email summary threshold is <%= @alert.rollup_threshold %>, we're taking your email alerts out of summary mode now. You'll now be emailed individually for each alerting check.</p>
|
42
42
|
<% else %>
|
43
|
-
<p>Your email alerts are being summarised as your email summary threshold is set to <%= @rollup_threshold %>. You'll receive summary emails like this one until your number of alerting checks falls below <%= @rollup_threshold %>.</p>
|
43
|
+
<p>Your email alerts are being summarised as your email summary threshold is set to <%= @alert.rollup_threshold %>. You'll receive summary emails like this one until your number of alerting checks falls below <%= @alert.rollup_threshold %>.</p>
|
44
44
|
<% end %>
|
45
45
|
|
46
46
|
<p>Cheers,<br/>
|
@@ -1,18 +1,18 @@
|
|
1
|
-
Hi <%= @contact_first_name %>
|
1
|
+
Hi <%= @alert.contact_first_name %>
|
2
2
|
|
3
|
-
You have <%= @rollup_alerts.length %> alerting check<%= @rollup_alerts.length == 1 ? '' : 's' %> as follows:
|
3
|
+
You have <%= @alert.rollup_alerts.length %> alerting check<%= @alert.rollup_alerts.length == 1 ? '' : 's' %> as follows:
|
4
4
|
|
5
|
-
<% @rollup_alerts.sort_by {|entity_check, details| details['duration'] }.each do |rollup_alert| -%>
|
5
|
+
<% @alert.rollup_alerts.sort_by {|entity_check, details| details['duration'] }.each do |rollup_alert| -%>
|
6
6
|
<% r_entity, r_check = rollup_alert[0].split(':', 2) -%>
|
7
7
|
<% state = rollup_alert[1]['state'] -%>
|
8
|
-
<% duration = ChronicDuration.output(rollup_alert[1]['duration']) -%>
|
8
|
+
<% duration = ChronicDuration.output(rollup_alert[1]['duration'] ) -%>
|
9
9
|
* <%= r_check %> on <%= r_entity %> is <%= ['ok'].include?(state) ? state.upcase : state.titleize %> (<%= duration %>)
|
10
10
|
<% end -%>
|
11
11
|
|
12
|
-
<% if @rollup
|
13
|
-
As your email summary threshold is <%= @rollup_threshold %>, we're taking your email alerts out of summary mode now. You'll now be emailed individually for each alerting check.
|
12
|
+
<% if @alert.rollup == 'recovery' -%>
|
13
|
+
As your email summary threshold is <%= @alert.rollup_threshold %>, we're taking your email alerts out of summary mode now. You'll now be emailed individually for each alerting check.
|
14
14
|
<% else -%>
|
15
|
-
Your email alerts are being summarised as your email summary threshold is set to <%= @rollup_threshold %>. You'll receive summary emails like this one until your number of alerting checks falls below <%= @rollup_threshold %>.
|
15
|
+
Your email alerts are being summarised as your email summary threshold is set to <%= @alert.rollup_threshold %>. You'll receive summary emails like this one until your number of alerting checks falls below <%= @alert.rollup_threshold %>.
|
16
16
|
<% end -%>
|
17
17
|
|
18
18
|
Cheers,
|
@@ -1,19 +1 @@
|
|
1
|
-
|
2
|
-
state_counts = @rollup_alerts.inject({}) do |memo, alert|
|
3
|
-
puts "alert: #{alert.inspect}"
|
4
|
-
memo[alert[1]['state']] = (memo[alert[1]['state']] || 0) + 1
|
5
|
-
memo
|
6
|
-
end
|
7
|
-
states_summary = ['critical', 'warning', 'unknown'].inject([]) do |memo, state|
|
8
|
-
next memo unless state_counts[state]
|
9
|
-
memo << "#{state.titleize}: #{state_counts[state]}"
|
10
|
-
memo
|
11
|
-
end.join(', ')
|
12
|
-
-%>
|
13
|
-
<% case @rollup -%>
|
14
|
-
<% when "problem" -%>
|
15
|
-
<%= "Problem summary: " -%>
|
16
|
-
<% when "recovery" -%>
|
17
|
-
<%= "Problem summaries finishing: " -%>
|
18
|
-
<% end -%>
|
19
|
-
<%= states_summary -%>
|
1
|
+
<%= @alert.type_sentence_case %>: <%= @alert.rollup_states_summary -%>
|
@@ -12,6 +12,7 @@ require 'flapjack/data/entity_check'
|
|
12
12
|
require 'flapjack/redis_pool'
|
13
13
|
require 'flapjack/utility'
|
14
14
|
require 'flapjack/version'
|
15
|
+
require 'flapjack/data/alert'
|
15
16
|
|
16
17
|
module Flapjack
|
17
18
|
|
@@ -482,14 +483,21 @@ module Flapjack
|
|
482
483
|
# FIXME: should also check if presence has been established in any group chat rooms that are
|
483
484
|
# configured before starting to process events, otherwise the first few may get lost (send
|
484
485
|
# before joining the group chat rooms)
|
485
|
-
|
486
|
-
@logger.debug("
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
486
|
+
unless connected?
|
487
|
+
@logger.debug("not connected, sleep 1 before retry")
|
488
|
+
EM::Synchrony.sleep(1)
|
489
|
+
next
|
490
|
+
end
|
491
|
+
|
492
|
+
@logger.debug("jabber is connected so commencing blpop on #{queue}")
|
493
|
+
events[queue] = @redis.blpop(queue, 0)
|
494
|
+
event_json = events[queue][1]
|
495
|
+
begin
|
496
|
+
event = Oj.load(event_json)
|
497
|
+
|
498
|
+
@logger.debug('jabber notification event received: ' + event.inspect)
|
499
|
+
|
500
|
+
if 'shutdown'.eql?(event['notification_type'])
|
493
501
|
@logger.debug("@should_quit: #{@should_quit}")
|
494
502
|
if @should_quit
|
495
503
|
EventMachine::Synchrony.next_tick do
|
@@ -497,49 +505,51 @@ module Flapjack
|
|
497
505
|
close # Blather::Client.close
|
498
506
|
end
|
499
507
|
end
|
500
|
-
|
501
|
-
|
502
|
-
state = event['state']
|
503
|
-
summary = event['summary']
|
504
|
-
duration = event['duration'] ? time_period_in_words(event['duration']) : '4 hours'
|
505
|
-
address = event['address']
|
506
|
-
|
507
|
-
@logger.debug("processing jabber notification address: #{address}, event: #{entity}:#{check}, state: #{state}, summary: #{summary}")
|
508
|
-
|
509
|
-
ack_str =
|
510
|
-
event['event_count'] &&
|
511
|
-
!state.eql?('ok') &&
|
512
|
-
!'acknowledgement'.eql?(type) &&
|
513
|
-
!'test'.eql?(type) ?
|
514
|
-
"::: #{@config['alias']}: ACKID #{event['event_count']} " : ''
|
515
|
-
|
516
|
-
type = 'unknown' unless type
|
517
|
-
|
518
|
-
maint_str = case type
|
519
|
-
when 'acknowledgement'
|
520
|
-
"has been acknowledged, unscheduled maintenance created for #{duration}"
|
521
|
-
when 'test'
|
522
|
-
''
|
523
|
-
else
|
524
|
-
"is #{state.upcase}"
|
525
|
-
end
|
508
|
+
next
|
509
|
+
end
|
526
510
|
|
527
|
-
|
528
|
-
# the logic isn't duplicated in each notification channel.
|
529
|
-
# TODO - templatise the messages so they can be customised without changing core code
|
530
|
-
headline = "test".eql?(type.downcase) ? "TEST NOTIFICATION" : type.upcase
|
511
|
+
alert = Flapjack::Data::Alert.new(event, :logger => @logger)
|
531
512
|
|
532
|
-
|
513
|
+
@logger.debug("processing jabber notification address: #{alert.address}, entity: #{alert.entity}, " +
|
514
|
+
"check: '#{alert.check}', state: #{alert.state}, summary: #{alert.summary}")
|
533
515
|
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
516
|
+
@ack_str =
|
517
|
+
alert.event_count &&
|
518
|
+
!alert.state.eql?('ok') &&
|
519
|
+
!'acknowledgement'.eql?(alert.type) &&
|
520
|
+
!'test'.eql?(alert.type) ?
|
521
|
+
"#{@config['alias']}: ACKID #{event['event_count']}" : nil
|
522
|
+
|
523
|
+
message_type = alert.rollup ? 'rollup' : 'alert'
|
524
|
+
|
525
|
+
mydir = File.dirname(__FILE__)
|
526
|
+
message_template_path = mydir + "/jabber/#{message_type}.text.erb"
|
527
|
+
message_template = ERB.new(File.read(message_template_path), nil, '-')
|
528
|
+
|
529
|
+
@alert = alert
|
530
|
+
bnd = binding
|
531
|
+
|
532
|
+
begin
|
533
|
+
message = message_template.result(bnd).chomp
|
534
|
+
rescue => e
|
535
|
+
@logger.error "Error while excuting the ERB for a jabber message, " +
|
536
|
+
"ERB being executed: #{message_template_path}"
|
537
|
+
raise
|
539
538
|
end
|
540
|
-
|
541
|
-
|
542
|
-
|
539
|
+
|
540
|
+
chat_type = :chat
|
541
|
+
chat_type = :groupchat if @config['rooms'] && @config['rooms'].include?(alert.address)
|
542
|
+
EventMachine::Synchrony.next_tick do
|
543
|
+
say(Blather::JID.new(alert.address), message, chat_type)
|
544
|
+
alert.record_send_success!
|
545
|
+
end
|
546
|
+
|
547
|
+
rescue => e
|
548
|
+
# TODO: have non-fatal errors generate messages (eg via flapjack events or straight to
|
549
|
+
# rollbar or similar)
|
550
|
+
@logger.error "Error generating or dispatching jabber message: #{e.class}: #{e.message}\n" +
|
551
|
+
e.backtrace.join("\n")
|
552
|
+
@logger.debug "Message that could not be processed: \n" + event_json
|
543
553
|
end
|
544
554
|
end
|
545
555
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%= @alert.type_sentence_case -%>
|
2
|
+
: <% if @ack_str %><%= @ack_str %>, <% end -%>
|
3
|
+
"<%= @alert.check %>" on <%= @alert.entity -%>
|
4
|
+
<% unless ['acknowledgement', 'test'].include?(@alert.type) -%>
|
5
|
+
is <%= @alert.state_title_case -%>
|
6
|
+
<% end -%>
|
7
|
+
<% if ['acknowledgement'].include?(@alert.type) -%>
|
8
|
+
has been acknowledged, unscheduled maintenance created for <%= time_period_in_words(@alert.acknowledgement_duration) -%>
|
9
|
+
<% end -%>
|
10
|
+
<% if @alert.summary && @alert.summary.length > 0 -%>
|
11
|
+
, <%= @alert.summary -%>
|
12
|
+
<% end -%>
|
@@ -1,5 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
require 'em-hiredis'
|
3
4
|
require 'em-synchrony'
|
4
5
|
require 'em-synchrony/em-http'
|
5
6
|
|
@@ -7,7 +8,9 @@ require 'oj'
|
|
7
8
|
|
8
9
|
require 'flapjack/data/entity_check'
|
9
10
|
require 'flapjack/data/global'
|
11
|
+
require 'flapjack/data/alert'
|
10
12
|
require 'flapjack/redis_pool'
|
13
|
+
require 'flapjack/utility'
|
11
14
|
|
12
15
|
module Flapjack
|
13
16
|
|
@@ -17,6 +20,8 @@ module Flapjack
|
|
17
20
|
PAGERDUTY_EVENTS_API_URL = 'https://events.pagerduty.com/generic/2010-04-15/create_event.json'
|
18
21
|
SEM_PAGERDUTY_ACKS_RUNNING = 'sem_pagerduty_acks_running'
|
19
22
|
|
23
|
+
include Flapjack::Utility
|
24
|
+
|
20
25
|
def initialize(opts = {})
|
21
26
|
@config = opts[:config]
|
22
27
|
@logger = opts[:logger]
|
@@ -60,42 +65,58 @@ module Flapjack
|
|
60
65
|
until @should_quit
|
61
66
|
@logger.debug("pagerduty gateway is going into blpop mode on #{queue}")
|
62
67
|
events[queue] = @redis.blpop(queue, 0)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
68
|
+
event_json = events[queue][1]
|
69
|
+
|
70
|
+
begin
|
71
|
+
event = Oj.load(event_json)
|
72
|
+
@logger.debug("pagerduty notification event received: " + event.inspect)
|
73
|
+
|
74
|
+
if 'shutdown'.eql?(event['notification_type'])
|
75
|
+
@logger.debug("@should_quit: #{@should_quit}")
|
76
|
+
next
|
77
|
+
end
|
78
|
+
|
79
|
+
alert = Flapjack::Data::Alert.new(event, :logger => @logger)
|
80
|
+
@logger.debug("processing pagerduty notification service_key: #{alert.address}, entity: #{alert.entity}, " +
|
81
|
+
"check: '#{alert.check}', state: #{alert.state}, summary: #{alert.summary}")
|
82
|
+
|
83
|
+
mydir = File.dirname(__FILE__)
|
84
|
+
message_template_path = mydir + "/pagerduty/alert.text.erb"
|
85
|
+
message_template = ERB.new(File.read(message_template_path), nil, '-')
|
86
|
+
|
87
|
+
@alert = alert
|
88
|
+
bnd = binding
|
89
|
+
|
90
|
+
begin
|
91
|
+
message = message_template.result(bnd).chomp
|
92
|
+
rescue => e
|
93
|
+
@logger.error "Error while excuting the ERB for a pagerduty message, " +
|
94
|
+
"ERB being executed: #{message_template_path}"
|
95
|
+
raise
|
96
|
+
end
|
97
|
+
|
98
|
+
pagerduty_type = case alert.type
|
76
99
|
when 'acknowledgement'
|
77
|
-
|
78
|
-
pagerduty_type = 'acknowledge'
|
100
|
+
'acknowledge'
|
79
101
|
when 'problem'
|
80
|
-
|
81
|
-
pagerduty_type = "trigger"
|
102
|
+
'trigger'
|
82
103
|
when 'recovery'
|
83
|
-
|
84
|
-
pagerduty_type = "resolve"
|
104
|
+
'resolve'
|
85
105
|
when 'test'
|
86
|
-
|
87
|
-
pagerduty_type = "trigger"
|
88
|
-
headline = "TEST NOTIFICATION"
|
106
|
+
'trigger'
|
89
107
|
end
|
90
108
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
:event_type => pagerduty_type,
|
96
|
-
:description => message }
|
109
|
+
pagerduty_event = { 'service_key' => alert.address,
|
110
|
+
'incident_key' => alert.event_id,
|
111
|
+
'event_type' => pagerduty_type,
|
112
|
+
'description' => message }
|
97
113
|
|
98
114
|
send_pagerduty_event(pagerduty_event)
|
115
|
+
alert.record_send_success!
|
116
|
+
rescue => e
|
117
|
+
@logger.error "Error generating or dispatching pagerduty message: #{e.class}: #{e.message}\n" +
|
118
|
+
e.backtrace.join("\n")
|
119
|
+
@logger.debug "Message that could not be processed: \n" + event_json
|
99
120
|
end
|
100
121
|
end
|
101
122
|
|
@@ -143,6 +164,10 @@ module Flapjack
|
|
143
164
|
response = Oj.load(http.response)
|
144
165
|
status = http.response_header.status
|
145
166
|
@logger.debug "send_pagerduty_event got a return code of #{status.to_s} - #{response.inspect}"
|
167
|
+
unless status == 200
|
168
|
+
raise "Error sending event to pagerduty: status: #{status.to_s} - #{response.inspect}" +
|
169
|
+
" posted data: #{options[:body]}"
|
170
|
+
end
|
146
171
|
[status, response]
|
147
172
|
end
|
148
173
|
|
@@ -187,10 +212,15 @@ module Flapjack
|
|
187
212
|
if !pg_acknowledged_by.nil? && !pg_acknowledged_by['name'].nil?
|
188
213
|
who_text = " by #{pg_acknowledged_by['name']}"
|
189
214
|
end
|
215
|
+
|
216
|
+
# FIXME: decide where the default acknowledgement period should reside and use it
|
217
|
+
# everywhere ... a case for moving configuration into redis (from config file) perhaps?
|
218
|
+
four_hours = 4 * 60 * 60
|
190
219
|
Flapjack::Data::Event.create_acknowledgement(
|
191
220
|
entity_name, check,
|
192
|
-
:summary
|
193
|
-
:
|
221
|
+
:summary => "Acknowledged on PagerDuty" + who_text,
|
222
|
+
:duration => four_hours,
|
223
|
+
:redis => @redis)
|
194
224
|
end
|
195
225
|
|
196
226
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%= @alert.type_sentence_case %>: "<%= @alert.check %>" on <%= @alert.entity -%>
|
2
|
+
<% unless ['acknowledgement', 'test'].include?(@alert.notification_type) -%>
|
3
|
+
is <%= @alert.state_title_case -%>
|
4
|
+
<% end -%>
|
5
|
+
<% if ['acknowledgement'].include?(@alert.type) -%>
|
6
|
+
has been acknowledged, unscheduled maintenance created for <%= time_period_in_words(@alert.acknowledgement_duration) -%>
|
7
|
+
<% end -%>
|
8
|
+
<% if @alert.summary && @alert.summary.length > 0 -%>
|
9
|
+
, <%= @alert.summary -%>
|
10
|
+
<% end -%>
|
@@ -4,6 +4,9 @@ require 'em-synchrony'
|
|
4
4
|
require 'em-synchrony/em-http'
|
5
5
|
require 'active_support/inflector'
|
6
6
|
|
7
|
+
require 'flapjack/data/alert'
|
8
|
+
require 'flapjack/utility'
|
9
|
+
|
7
10
|
module Flapjack
|
8
11
|
module Gateways
|
9
12
|
class SmsMessagenet
|
@@ -12,41 +15,39 @@ module Flapjack
|
|
12
15
|
|
13
16
|
class << self
|
14
17
|
|
18
|
+
include Flapjack::Utility
|
19
|
+
|
15
20
|
def start
|
16
21
|
@sent = 0
|
17
22
|
end
|
18
23
|
|
19
|
-
def perform(
|
20
|
-
@logger.debug "Woo, got a notification to send out: #{
|
24
|
+
def perform(contents)
|
25
|
+
@logger.debug "Woo, got a notification to send out: #{contents.inspect}"
|
26
|
+
alert = Flapjack::Data::Alert.new(contents, :logger => @logger)
|
21
27
|
|
22
28
|
endpoint = @config["endpoint"] || MESSAGENET_DEFAULT_URL
|
23
29
|
username = @config["username"]
|
24
30
|
password = @config["password"]
|
25
31
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
@state = notification['state']
|
30
|
-
@summary = notification['summary']
|
31
|
-
@time = notification['time']
|
32
|
-
@entity_name, @check = notification['event_id'].split(':', 2)
|
33
|
-
address = notification['address']
|
34
|
-
notification_id = notification['id']
|
35
|
-
|
36
|
-
message_type = case
|
37
|
-
when @rollup
|
38
|
-
'rollup'
|
39
|
-
else
|
40
|
-
'alert'
|
41
|
-
end
|
32
|
+
address = alert.address
|
33
|
+
notification_id = alert.notification_id
|
34
|
+
message_type = alert.rollup ? 'rollup' : 'alert'
|
42
35
|
|
43
|
-
|
44
|
-
|
36
|
+
my_dir = File.dirname(__FILE__)
|
37
|
+
sms_template_path = my_dir + "/sms_messagenet/#{message_type}.text.erb"
|
38
|
+
sms_template = ERB.new(File.read(sms_template_path), nil, '-')
|
45
39
|
|
40
|
+
@alert = alert
|
46
41
|
bnd = binding
|
47
|
-
message = sms_template.result(bnd).chomp
|
48
42
|
|
49
|
-
|
43
|
+
begin
|
44
|
+
message = sms_template.result(bnd).chomp
|
45
|
+
rescue => e
|
46
|
+
@logger.error "Error while excuting the ERB for an sms: " +
|
47
|
+
"ERB being executed: #{sms_template_path}"
|
48
|
+
raise
|
49
|
+
end
|
50
|
+
|
50
51
|
if @config.nil? || (@config.respond_to?(:empty?) && @config.empty?)
|
51
52
|
@logger.error "Messagenet config is missing"
|
52
53
|
return
|
@@ -82,25 +83,17 @@ module Flapjack
|
|
82
83
|
status = (http.nil? || http.response_header.nil?) ? nil : http.response_header.status
|
83
84
|
if (status >= 200) && (status <= 206)
|
84
85
|
@sent += 1
|
85
|
-
|
86
|
+
alert.record_send_success!
|
87
|
+
@logger.debug "Sent SMS via Messagenet, response status is #{status}, " +
|
86
88
|
"notification_id: #{notification_id}"
|
87
89
|
else
|
88
90
|
@logger.error "Failed to send SMS via Messagenet, response status is #{status}, " +
|
89
91
|
"notification_id: #{notification_id}"
|
90
92
|
end
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
def truncate(str, length, options = {})
|
96
|
-
text = str.dup
|
97
|
-
options[:omission] ||= "..."
|
98
|
-
|
99
|
-
length_with_room_for_omission = length - options[:omission].length
|
100
|
-
stop = options[:separator] ?
|
101
|
-
(text.rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission) : length_with_room_for_omission
|
102
|
-
|
103
|
-
(text.length > length ? text[0...stop] + options[:omission] : text).to_s
|
93
|
+
rescue => e
|
94
|
+
@logger.error "Error generating or delivering sms to #{contents['address']}: #{e.class}: #{e.message}"
|
95
|
+
@logger.error e.backtrace.join("\n")
|
96
|
+
raise
|
104
97
|
end
|
105
98
|
|
106
99
|
end
|