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
@@ -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
|