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.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +10 -0
  3. data/features/notification_rules.feature +25 -25
  4. data/features/rollup.feature +38 -18
  5. data/features/steps/events_steps.rb +10 -5
  6. data/features/steps/notifications_steps.rb +8 -4
  7. data/lib/flapjack/data/alert.rb +207 -0
  8. data/lib/flapjack/data/contact.rb +14 -7
  9. data/lib/flapjack/data/entity_check.rb +4 -3
  10. data/lib/flapjack/data/notification.rb +28 -27
  11. data/lib/flapjack/gateways/api/contact_methods.rb +32 -12
  12. data/lib/flapjack/gateways/email.rb +49 -53
  13. data/lib/flapjack/gateways/email/alert.html.erb +15 -15
  14. data/lib/flapjack/gateways/email/alert.text.erb +15 -15
  15. data/lib/flapjack/gateways/email/alert_subject.text.erb +3 -13
  16. data/lib/flapjack/gateways/email/rollup.html.erb +6 -6
  17. data/lib/flapjack/gateways/email/rollup.text.erb +7 -7
  18. data/lib/flapjack/gateways/email/rollup_subject.text.erb +1 -19
  19. data/lib/flapjack/gateways/jabber.rb +57 -47
  20. data/lib/flapjack/gateways/jabber/alert.text.erb +12 -0
  21. data/lib/flapjack/gateways/jabber/rollup.text.erb +2 -0
  22. data/lib/flapjack/gateways/pagerduty.rb +60 -30
  23. data/lib/flapjack/gateways/pagerduty/alert.text.erb +10 -0
  24. data/lib/flapjack/gateways/sms_messagenet.rb +29 -36
  25. data/lib/flapjack/gateways/sms_messagenet/alert.text.erb +4 -14
  26. data/lib/flapjack/gateways/sms_messagenet/rollup.text.erb +2 -34
  27. data/lib/flapjack/gateways/web.rb +23 -14
  28. data/lib/flapjack/gateways/web/views/check.html.erb +16 -11
  29. data/lib/flapjack/gateways/web/views/contact.html.erb +58 -16
  30. data/lib/flapjack/gateways/web/views/self_stats.html.erb +80 -71
  31. data/lib/flapjack/notifier.rb +8 -2
  32. data/lib/flapjack/pikelet.rb +17 -3
  33. data/lib/flapjack/processor.rb +0 -1
  34. data/lib/flapjack/redis_pool.rb +1 -1
  35. data/lib/flapjack/utility.rb +13 -0
  36. data/lib/flapjack/version.rb +1 -1
  37. data/spec/lib/flapjack/data/contact_spec.rb +44 -29
  38. data/spec/lib/flapjack/gateways/api/contact_methods_spec.rb +24 -4
  39. data/spec/lib/flapjack/gateways/email_spec.rb +0 -5
  40. data/spec/lib/flapjack/gateways/jabber_spec.rb +5 -1
  41. data/spec/lib/flapjack/gateways/pagerduty_spec.rb +5 -2
  42. data/spec/lib/flapjack/gateways/{sms_messagenet.spec.rb → sms_messagenet_spec.rb} +16 -12
  43. data/spec/lib/flapjack/gateways/web_spec.rb +1 -1
  44. data/spec/spec_helper.rb +28 -6
  45. 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: <%= @entity_name %>
6
- Check: <%= @check %>
7
- State: <%= ['ok'].include?(@state) ? @state.upcase : @state.titleize %>
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 @duration && @duration > 40 -%>
16
- Duration: <%= ChronicDuration.output(@duration) %>
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: <%= ['ok'].include?(@last_state) ? @last_state.upcase : @last_state.titleize %>
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
- <% case @notification_type -%>
2
- <% when "problem" -%>
3
- <%= "Problem: " -%>
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.downcase == 'recovery' %>
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.downcase == 'recovery' -%>
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
- if connected?
486
- @logger.debug("jabber is connected so commencing blpop on #{queue}")
487
- events[queue] = @redis.blpop(queue, 0)
488
- event = Oj.load(events[queue][1])
489
- type = event['notification_type'] || 'unknown'
490
- @logger.debug('jabber notification event received')
491
- @logger.debug(event.inspect)
492
- if 'shutdown'.eql?(type)
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
- else
501
- entity, check = event['event_id'].split(':', 2)
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
- # FIXME - should probably put all the message composition stuff in one place so
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
- msg = "#{headline} #{ack_str}::: \"#{check}\" on #{entity} #{maint_str} ::: #{summary}"
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
- chat_type = :chat
535
- chat_type = :groupchat if @config['rooms'] && @config['rooms'].include?(address)
536
- EventMachine::Synchrony.next_tick do
537
- say(Blather::JID.new(address), msg, chat_type)
538
- end
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
- else
541
- @logger.debug("not connected, sleep 1 before retry")
542
- EM::Synchrony.sleep(1)
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 -%>
@@ -0,0 +1,2 @@
1
+ <%= @alert.type_sentence_case %>: <%= @alert.rollup_states_summary -%>
2
+ (<%= @alert.rollup_states_detail_text(:max_checks_per_state => 10) -%>)
@@ -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
- event = Oj.load(events[queue][1])
64
- type = event['notification_type']
65
- @logger.debug("pagerduty notification event popped off the queue: " + event.inspect)
66
- unless 'shutdown'.eql?(type)
67
- event_id = event['event_id']
68
- entity, check = event_id.split(':', 2)
69
- state = event['state']
70
- summary = event['summary']
71
- address = event['address']
72
-
73
- headline = type.upcase
74
-
75
- case type.downcase
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
- maint_str = "has been acknowledged"
78
- pagerduty_type = 'acknowledge'
100
+ 'acknowledge'
79
101
  when 'problem'
80
- maint_str = "is #{state.upcase}"
81
- pagerduty_type = "trigger"
102
+ 'trigger'
82
103
  when 'recovery'
83
- maint_str = "is #{state.upcase}"
84
- pagerduty_type = "resolve"
104
+ 'resolve'
85
105
  when 'test'
86
- maint_str = ""
87
- pagerduty_type = "trigger"
88
- headline = "TEST NOTIFICATION"
106
+ 'trigger'
89
107
  end
90
108
 
91
- message = "#{type.upcase} - \"#{check}\" on #{entity} #{maint_str} - #{summary}"
92
-
93
- pagerduty_event = { :service_key => address,
94
- :incident_key => event_id,
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 => "Acknowledged on PagerDuty" + who_text,
193
- :redis => @redis)
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(notification)
20
- @logger.debug "Woo, got a notification to send out: #{notification.inspect}"
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
- @notification_type = notification['notification_type']
27
- @rollup = notification['rollup']
28
- @rollup_alerts = notification['rollup_alerts']
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
- sms_template = ERB.new(File.read(File.dirname(__FILE__) +
44
- "/sms_messagenet/#{message_type}.text.erb"), nil, '-')
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
- # TODO log error and skip instead of raising errors
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
- @logger.info "Sent SMS via Messagenet, response status is #{status}, " +
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
- end
93
-
94
- # copied from ActiveSupport
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