flapjack 1.2.1 → 1.2.2

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/.travis.yml +11 -12
  4. data/CHANGELOG.md +10 -0
  5. data/Gemfile +0 -7
  6. data/Rakefile +0 -1
  7. data/bin/flapjack +2 -0
  8. data/etc/flapjack_config.yaml.example +20 -0
  9. data/features/ack_after_sched_maint.feature +1 -1
  10. data/features/cli.feature +1 -1
  11. data/features/notification_rules.feature +1 -1
  12. data/features/notifications.feature +0 -9
  13. data/features/rollup.feature +1 -1
  14. data/features/steps/events_steps.rb +20 -8
  15. data/features/steps/notifications_steps.rb +62 -75
  16. data/features/support/env.rb +17 -8
  17. data/flapjack.gemspec +4 -4
  18. data/lib/flapjack.rb +3 -0
  19. data/lib/flapjack/cli/import.rb +1 -0
  20. data/lib/flapjack/cli/maintenance.rb +1 -0
  21. data/lib/flapjack/cli/purge.rb +2 -0
  22. data/lib/flapjack/cli/receiver.rb +1 -0
  23. data/lib/flapjack/cli/simulate.rb +1 -0
  24. data/lib/flapjack/data/alert.rb +28 -1
  25. data/lib/flapjack/data/contact.rb +1 -1
  26. data/lib/flapjack/data/entity.rb +18 -8
  27. data/lib/flapjack/data/entity_check.rb +17 -0
  28. data/lib/flapjack/data/event.rb +33 -15
  29. data/lib/flapjack/data/migration.rb +46 -23
  30. data/lib/flapjack/filters/delays.rb +13 -6
  31. data/lib/flapjack/gateways/aws_sns.rb +115 -88
  32. data/lib/flapjack/gateways/aws_sns/alert.text.erb +2 -1
  33. data/lib/flapjack/gateways/email.rb +145 -135
  34. data/lib/flapjack/gateways/email/alert.html.erb +6 -4
  35. data/lib/flapjack/gateways/email/alert.text.erb +2 -0
  36. data/lib/flapjack/gateways/jabber.rb +61 -1
  37. data/lib/flapjack/gateways/jabber/alert.text.erb +1 -1
  38. data/lib/flapjack/gateways/pagerduty/alert.text.erb +1 -1
  39. data/lib/flapjack/gateways/sms_gammu.rb +119 -0
  40. data/lib/flapjack/gateways/sms_messagenet.rb +95 -67
  41. data/lib/flapjack/gateways/sms_messagenet/alert.text.erb +2 -1
  42. data/lib/flapjack/gateways/sms_twilio.rb +102 -74
  43. data/lib/flapjack/gateways/sms_twilio/alert.text.erb +2 -1
  44. data/lib/flapjack/logger.rb +1 -1
  45. data/lib/flapjack/notifier.rb +5 -14
  46. data/lib/flapjack/patches.rb +0 -58
  47. data/lib/flapjack/pikelet.rb +8 -78
  48. data/lib/flapjack/processor.rb +3 -1
  49. data/lib/flapjack/redis_pool.rb +2 -0
  50. data/lib/flapjack/version.rb +1 -1
  51. data/spec/lib/flapjack/data/contact_spec.rb +2 -2
  52. data/spec/lib/flapjack/data/entity_spec.rb +15 -0
  53. data/spec/lib/flapjack/data/event_spec.rb +2 -2
  54. data/spec/lib/flapjack/data/migration_spec.rb +11 -0
  55. data/spec/lib/flapjack/gateways/aws_sns_spec.rb +12 -8
  56. data/spec/lib/flapjack/gateways/email_spec.rb +56 -51
  57. data/spec/lib/flapjack/gateways/sms_messagenet_spec.rb +17 -12
  58. data/spec/lib/flapjack/gateways/sms_twilio_spec.rb +17 -12
  59. data/spec/lib/flapjack/pikelet_spec.rb +9 -23
  60. data/spec/lib/flapjack/redis_pool_spec.rb +1 -0
  61. data/tasks/profile.rake +25 -109
  62. metadata +37 -39
  63. data/Gemfile-ruby1.9 +0 -30
  64. data/Gemfile-ruby1.9.lock +0 -250
  65. data/tasks/benchmarks.rake +0 -237
@@ -20,8 +20,15 @@ module Flapjack
20
20
  include Base
21
21
 
22
22
  def block?(event, entity_check, previous_state)
23
- failure_delay = 30
24
- resend_delay = 60
23
+ initial_failure_delay = entity_check.initial_failure_delay
24
+ if initial_failure_delay.nil? || (initial_failure_delay < 0)
25
+ initial_failure_delay = Flapjack::DEFAULT_INITIAL_FAILURE_DELAY
26
+ end
27
+
28
+ repeat_failure_delay = entity_check.repeat_failure_delay
29
+ if repeat_failure_delay.nil? || (repeat_failure_delay < 0)
30
+ repeat_failure_delay = Flapjack::DEFAULT_REPEAT_FAILURE_DELAY
31
+ end
25
32
 
26
33
  label = 'Filter: Delays:'
27
34
 
@@ -51,18 +58,18 @@ module Flapjack
51
58
  "event.state: [#{event.state.inspect}], " +
52
59
  "last_alert_state == event.state ? #{last_alert_state.to_s == event.state}")
53
60
 
54
- if current_state_duration < failure_delay
61
+ if current_state_duration < initial_failure_delay
55
62
  @logger.debug("#{label} block - duration of current failure " +
56
- "(#{current_state_duration}) is less than failure_delay (#{failure_delay})")
63
+ "(#{current_state_duration}) is less than initial_failure_delay (#{initial_failure_delay})")
57
64
  return true
58
65
  end
59
66
 
60
- if !last_problem_alert.nil? && (time_since_last_alert < resend_delay) &&
67
+ if !last_problem_alert.nil? && (time_since_last_alert < repeat_failure_delay) &&
61
68
  (last_alert_state.to_s == event.state)
62
69
 
63
70
  @logger.debug("#{label} block - time since last alert for " +
64
71
  "current problem (#{time_since_last_alert}) is less than " +
65
- "resend_delay (#{resend_delay}) and last alert state (#{last_alert_state}) " +
72
+ "repeat_failure_delay (#{repeat_failure_delay}) and last alert state (#{last_alert_state}) " +
66
73
  "is equal to current event state (#{event.state})")
67
74
  return true
68
75
  end
@@ -4,6 +4,8 @@ require 'em-synchrony'
4
4
  require 'em-synchrony/em-http'
5
5
  require 'active_support/inflector'
6
6
 
7
+ require 'flapjack/redis_pool'
8
+
7
9
  require 'flapjack/data/alert'
8
10
  require 'flapjack/utility'
9
11
 
@@ -13,121 +15,146 @@ module Flapjack
13
15
 
14
16
  SNS_DEFAULT_REGION_NAME = 'us-east-1'
15
17
 
16
- class << self
18
+ include Flapjack::Utility
17
19
 
18
- include Flapjack::Utility
20
+ def initialize(opts = {})
21
+ @config = opts[:config]
22
+ @logger = opts[:logger]
23
+ @redis_config = opts[:redis_config] || {}
24
+ @redis = Flapjack::RedisPool.new(:config => @redis_config, :size => 1, :logger => @logger)
19
25
 
20
- def start
21
- @sent = 0
22
- end
26
+ @logger.info("starting")
27
+ @logger.debug("new aws_sns gateway pikelet with the following options: #{@config.inspect}")
23
28
 
24
- def perform(contents)
25
- @logger.debug "Received a notification: #{contents.inspect}"
26
- alert = Flapjack::Data::Alert.new(contents, :logger => @logger)
27
-
28
- region_name = @config["region_name"] || SNS_DEFAULT_REGION_NAME
29
- hostname = "sns.#{region_name}.amazonaws.com"
30
- endpoint = "http://#{hostname}/"
31
- access_key = @config["access_key"]
32
- secret_key = @config["secret_key"]
33
- timestamp = @config["timestamp"] || DateTime.now.iso8601
34
-
35
- address = alert.address
36
- notification_id = alert.notification_id
37
- message_type = alert.rollup ? 'rollup' : 'alert'
38
-
39
- my_dir = File.dirname(__FILE__)
40
- sms_template_path = case
41
- when @config.has_key?('templates') && @config['templates']["#{message_type}.text"]
42
- @config['templates']["#{message_type}.text"]
43
- else
44
- my_dir + "/aws_sns/#{message_type}.text.erb"
45
- end
46
- sms_template = ERB.new(File.read(sms_template_path), nil, '-')
29
+ @sent = 0
30
+ end
31
+
32
+ def stop
33
+ @logger.info("stopping")
34
+ @should_quit = true
35
+
36
+ redis_uri = @redis_config[:path] ||
37
+ "redis://#{@redis_config[:host] || '127.0.0.1'}:#{@redis_config[:port] || '6379'}/#{@redis_config[:db] || '0'}"
38
+ shutdown_redis = EM::Hiredis.connect(redis_uri)
39
+ shutdown_redis.rpush(@config['queue'], Flapjack.dump_json('notification_type' => 'shutdown'))
40
+ end
47
41
 
48
- @alert = alert
49
- bnd = binding
42
+ def start
43
+ queue = @config['queue']
50
44
 
45
+ until @should_quit
51
46
  begin
52
- message = sms_template.result(bnd).chomp
47
+ @logger.debug("aws_sns gateway is going into blpop mode on #{queue}")
48
+ deliver( Flapjack::Data::Alert.next(queue, :redis => @redis, :logger => @logger) )
53
49
  rescue => e
54
- @logger.error "Error while excuting the ERB for an sms: " +
55
- "ERB being executed: #{sms_template_path}"
56
- raise
50
+ @logger.error "Error generating or dispatching AWS SNS message: #{e.class}: #{e.message}\n" +
51
+ e.backtrace.join("\n")
57
52
  end
53
+ end
54
+ end
58
55
 
59
- if @config.nil? || (@config.respond_to?(:empty?) && @config.empty?)
60
- @logger.error "AWS SNS config is missing"
61
- return
62
- end
56
+ def deliver(alert)
57
+ region_name = @config["region_name"] || SNS_DEFAULT_REGION_NAME
58
+ hostname = "sns.#{region_name}.amazonaws.com"
59
+ endpoint = "http://#{hostname}/"
60
+ access_key = @config["access_key"]
61
+ secret_key = @config["secret_key"]
62
+ timestamp = @config["timestamp"] || DateTime.now.iso8601
63
+
64
+ address = alert.address
65
+ notification_id = alert.notification_id
66
+ message_type = alert.rollup ? 'rollup' : 'alert'
67
+
68
+ my_dir = File.dirname(__FILE__)
69
+ sms_template_path = case
70
+ when @config.has_key?('templates') && @config['templates']["#{message_type}.text"]
71
+ @config['templates']["#{message_type}.text"]
72
+ else
73
+ my_dir + "/aws_sns/#{message_type}.text.erb"
74
+ end
75
+ sms_template = ERB.new(File.read(sms_template_path), nil, '-')
63
76
 
64
- errors = []
77
+ @alert = alert
78
+ bnd = binding
65
79
 
66
- [[address, "AWS SNS topic ARN is missing"],
67
- [access_key, "AWS SNS access key is missing"],
68
- [secret_key, "AWS SNS secret key is missing"],
69
- [notification_id, "Notification id is missing"]].each do |val_err|
80
+ begin
81
+ message = sms_template.result(bnd).chomp
82
+ rescue => e
83
+ @logger.error "Error while excuting the ERB for an sms: " +
84
+ "ERB being executed: #{sms_template_path}"
85
+ raise
86
+ end
70
87
 
71
- next unless val_err.first.nil? || (val_err.first.respond_to?(:empty?) && val_err.first.empty?)
72
- errors << val_err.last
73
- end
88
+ if @config.nil? || (@config.respond_to?(:empty?) && @config.empty?)
89
+ @logger.error "AWS SNS config is missing"
90
+ return
91
+ end
74
92
 
75
- unless errors.empty?
76
- errors.each {|err| @logger.error err }
77
- return
78
- end
93
+ errors = []
79
94
 
95
+ [[address, "AWS SNS topic ARN is missing"],
96
+ [access_key, "AWS SNS access key is missing"],
97
+ [secret_key, "AWS SNS secret key is missing"],
98
+ [notification_id, "Notification id is missing"]].each do |val_err|
80
99
 
81
- query = {'Subject' => message,
82
- 'TopicArn' => address,
83
- 'Message' => message,
84
- 'Action' => 'Publish',
85
- 'SignatureVersion' => 2,
86
- 'SignatureMethod' => 'HmacSHA256',
87
- 'Timestamp' => timestamp,
88
- 'AWSAccessKeyId' => access_key}
100
+ next unless val_err.first.nil? || (val_err.first.respond_to?(:empty?) && val_err.first.empty?)
101
+ errors << val_err.last
102
+ end
89
103
 
90
- string_to_sign = string_to_sign('POST', hostname, "/", query)
104
+ unless errors.empty?
105
+ errors.each {|err| @logger.error err }
106
+ return
107
+ end
91
108
 
92
- query['Signature'] = get_signature(secret_key, string_to_sign)
109
+ query = {'Subject' => message,
110
+ 'TopicArn' => address,
111
+ 'Message' => message,
112
+ 'Action' => 'Publish',
113
+ 'SignatureVersion' => 2,
114
+ 'SignatureMethod' => 'HmacSHA256',
115
+ 'Timestamp' => timestamp,
116
+ 'AWSAccessKeyId' => access_key}
93
117
 
94
- http = EM::HttpRequest.new(endpoint).post(:query => query)
118
+ string_to_sign = self.class.string_to_sign('POST', hostname, "/", query)
95
119
 
96
- @logger.debug "server response: #{http.response}"
120
+ query['Signature'] = self.class.get_signature(secret_key, string_to_sign)
97
121
 
98
- status = (http.nil? || http.response_header.nil?) ? nil : http.response_header.status
99
- if (status >= 200) && (status <= 206)
100
- @sent += 1
101
- alert.record_send_success!
102
- @logger.debug "Sent notification via SNS, response status is #{status}, " +
103
- "notification_id: #{notification_id}"
104
- else
105
- @logger.error "Failed to send notification via SNS, response status is #{status}, " +
106
- "notification_id: #{notification_id}"
107
- end
108
- rescue => e
109
- @logger.error "Error generating or delivering notification to #{address}: #{e.class}: #{e.message}"
110
- @logger.error e.backtrace.join("\n")
111
- raise
112
- end
122
+ http = EM::HttpRequest.new(endpoint).post(:query => query)
113
123
 
114
- def get_signature(secret_key, string_to_sign)
115
- signature = OpenSSL::HMAC.digest('sha256', secret_key, string_to_sign)
124
+ @logger.debug "server response: #{http.response}"
116
125
 
117
- Base64.encode64(signature).strip
126
+ status = (http.nil? || http.response_header.nil?) ? nil : http.response_header.status
127
+ if (status >= 200) && (status <= 206)
128
+ @sent += 1
129
+ alert.record_send_success!
130
+ @logger.debug "Sent notification via SNS, response status is #{status}, " +
131
+ "notification_id: #{notification_id}"
132
+ else
133
+ @logger.error "Failed to send notification via SNS, response status is #{status}, " +
134
+ "notification_id: #{notification_id}"
118
135
  end
136
+ rescue => e
137
+ @logger.error "Error generating or delivering notification to #{address}: #{e.class}: #{e.message}"
138
+ @logger.error e.backtrace.join("\n")
139
+ raise
140
+ end
119
141
 
120
- def string_to_sign(method, host, uri, query)
121
- query = query.sort_by { |key, value| key }
142
+ def self.get_signature(secret_key, string_to_sign)
143
+ signature = OpenSSL::HMAC.digest('sha256', secret_key, string_to_sign)
122
144
 
123
- [method.upcase,
124
- host.downcase,
125
- uri,
126
- URI.encode_www_form(query)
127
- ].join("\n")
128
- end
145
+ Base64.encode64(signature).strip
146
+ end
147
+
148
+ def self.string_to_sign(method, host, uri, query)
149
+ query = query.sort_by { |key, value| key }
129
150
 
151
+ [method.upcase,
152
+ host.downcase,
153
+ uri,
154
+ URI.encode_www_form(query)
155
+ ].join("\n")
130
156
  end
157
+
131
158
  end
132
159
  end
133
160
  end
@@ -1,5 +1,6 @@
1
+ <% summary = @alert.summary %>
1
2
  <%= @alert.type_sentence_case %>: '<%= @alert.check %>' on <%= @alert.entity -%>
2
3
  <% unless ['acknowledgement', 'test'].include?(@alert.notification_type) -%>
3
4
  is <%= @alert.state_title_case -%>
4
5
  <% end -%>
5
- at <%= Time.at(@alert.time).strftime('%-d %b %H:%M') %>, <%= @alert.summary -%>
6
+ at <%= Time.at(@alert.time).strftime('%-d %b %H:%M') %><%= (summary.nil? || summary.empty?) ? '' : ", #{summary}" -%>
@@ -9,6 +9,7 @@ require 'active_support/inflector'
9
9
  require 'em-synchrony'
10
10
  require 'em/protocols/smtpclient'
11
11
 
12
+ require 'flapjack/redis_pool'
12
13
  require 'flapjack/utility'
13
14
 
14
15
  require 'flapjack/data/entity_check'
@@ -19,169 +20,178 @@ module Flapjack
19
20
 
20
21
  class Email
21
22
 
22
- class << self
23
+ include Flapjack::Utility
23
24
 
24
- include Flapjack::Utility
25
+ def initialize(opts = {})
26
+ @config = opts[:config]
27
+ @logger = opts[:logger]
28
+ @redis_config = opts[:redis_config] || {}
29
+ @redis = Flapjack::RedisPool.new(:config => @redis_config, :size => 1, :logger => @logger)
25
30
 
26
- def start
27
- @logger.info("starting")
28
- @logger.debug("new email gateway pikelet with the following options: #{@config.inspect}")
29
- @smtp_config = @config.delete('smtp_config')
30
- @sent = 0
31
- @fqdn = `/bin/hostname -f`.chomp
32
- end
33
-
34
- # TODO refactor to remove complexity
35
- def perform(contents)
36
- @logger.debug "Woo, got an alert to send out: #{contents.inspect}"
37
- alert = prepare(contents)
38
- deliver(alert)
39
- end
40
-
41
- # sets a bunch of class instance variables for each email
42
- def prepare(contents)
43
- Flapjack::Data::Alert.new(contents, :logger => @logger)
44
- rescue => e
45
- @logger.error "Error preparing email to #{contents['address']}: #{e.class}: #{e.message}"
46
- @logger.error e.backtrace.join("\n")
47
- raise
48
- end
31
+ @logger.info("starting")
32
+ @logger.debug("new email gateway pikelet with the following options: #{@config.inspect}")
33
+ @smtp_config = @config.delete('smtp_config')
34
+ @sent = 0
35
+ @fqdn = `/bin/hostname -f`.chomp
36
+ end
49
37
 
50
- def deliver(alert)
51
- host = @smtp_config ? @smtp_config['host'] : nil
52
- port = @smtp_config ? @smtp_config['port'] : nil
53
- starttls = @smtp_config ? !! @smtp_config['starttls'] : nil
54
- m_from = @smtp_config ? @smtp_config['from'] : "flapjack@#{@fqdn}"
55
- m_reply_to = @smtp_config ? ( @smtp_config['reply_to'] ||= m_from ) : "flapjack@#{@fqdn}"
56
- if @smtp_config
57
- if auth_config = @smtp_config['auth']
58
- auth = {}
59
- auth[:type] = auth_config['type'].to_sym || :plain
60
- auth[:username] = auth_config['username']
61
- auth[:password] = auth_config['password']
62
- end
63
- end
38
+ def stop
39
+ @logger.info("stopping")
40
+ @should_quit = true
64
41
 
65
- @logger.debug("flapjack_mailer: set from to #{m_from}")
42
+ redis_uri = @redis_config[:path] ||
43
+ "redis://#{@redis_config[:host] || '127.0.0.1'}:#{@redis_config[:port] || '6379'}/#{@redis_config[:db] || '0'}"
44
+ shutdown_redis = EM::Hiredis.connect(redis_uri)
45
+ shutdown_redis.rpush(@config['queue'], Flapjack.dump_json('notification_type' => 'shutdown'))
46
+ end
66
47
 
67
- mail = prepare_email(:from => m_from,
68
- :reply_to => m_reply_to,
69
- :to => alert.address,
70
- :message_id => "<#{alert.notification_id}@#{@fqdn}>",
71
- :alert => alert)
48
+ def start
49
+ queue = @config['queue']
72
50
 
73
- smtp_from = m_from.clone
74
- while smtp_from =~ /(<|>)/
75
- smtp_from.sub!(/^.*</, '')
76
- smtp_from.sub!(/>.*$/, '')
51
+ until @should_quit
52
+ begin
53
+ @logger.debug("email gateway is going into blpop mode on #{queue}")
54
+ deliver( Flapjack::Data::Alert.next(queue, :redis => @redis, :logger => @logger) )
55
+ rescue => e
56
+ @logger.error "Error generating or dispatching email message: #{e.class}: #{e.message}\n" +
57
+ e.backtrace.join("\n")
77
58
  end
59
+ end
60
+ end
78
61
 
79
- smtp_args = {:from => smtp_from,
80
- :to => alert.address,
81
- :content => "#{mail.to_s}\r\n.\r\n",
82
- :domain => @fqdn,
83
- :host => host || 'localhost',
84
- :port => port || 25,
85
- :starttls => starttls}
86
- smtp_args.merge!(:auth => auth) if auth
87
-
88
- email = EM::P::SmtpClient.send(smtp_args)
89
-
90
- response = EM::Synchrony.sync(email)
91
-
92
- # http://tools.ietf.org/html/rfc821#page-36 SMTP response codes
93
- if response && response.respond_to?(:code) &&
94
- ((response.code == 250) || (response.code == 251))
95
- alert.record_send_success!
96
- @sent += 1
97
- else
98
- @logger.error "Email sending failed"
62
+ def deliver(alert)
63
+ host = @smtp_config ? @smtp_config['host'] : nil
64
+ port = @smtp_config ? @smtp_config['port'] : nil
65
+ starttls = @smtp_config ? !! @smtp_config['starttls'] : nil
66
+ m_from = @smtp_config ? @smtp_config['from'] : "flapjack@#{@fqdn}"
67
+ m_reply_to = @smtp_config ? ( @smtp_config['reply_to'] ||= m_from ) : "flapjack@#{@fqdn}"
68
+ if @smtp_config
69
+ if auth_config = @smtp_config['auth']
70
+ auth = {}
71
+ auth[:type] = auth_config['type'].to_sym || :plain
72
+ auth[:username] = auth_config['username']
73
+ auth[:password] = auth_config['password']
99
74
  end
75
+ end
100
76
 
101
- @logger.debug "Email response: #{response.inspect}"
77
+ @logger.debug("flapjack_mailer: set from to #{m_from}")
102
78
 
103
- rescue => e
104
- @logger.error "Error generating or delivering email to #{alert.address}: #{e.class}: #{e.message}"
105
- @logger.error e.backtrace.join("\n")
106
- raise
79
+ mail = prepare_email(:from => m_from,
80
+ :reply_to => m_reply_to,
81
+ :to => alert.address,
82
+ :message_id => "<#{alert.notification_id}@#{@fqdn}>",
83
+ :alert => alert)
84
+
85
+ smtp_from = m_from.clone
86
+ while smtp_from =~ /(<|>)/
87
+ smtp_from.sub!(/^.*</, '')
88
+ smtp_from.sub!(/>.*$/, '')
107
89
  end
108
90
 
109
- private
91
+ smtp_args = {:from => smtp_from,
92
+ :to => alert.address,
93
+ :content => "#{mail.to_s}\r\n.\r\n",
94
+ :domain => @fqdn,
95
+ :host => host || 'localhost',
96
+ :port => port || 25,
97
+ :starttls => starttls}
98
+ smtp_args.merge!(:auth => auth) if auth
99
+
100
+ email = EM::P::SmtpClient.send(smtp_args)
101
+
102
+ response = EM::Synchrony.sync(email)
103
+
104
+ # http://tools.ietf.org/html/rfc821#page-36 SMTP response codes
105
+ if response && response.respond_to?(:code) &&
106
+ ((response.code == 250) || (response.code == 251))
107
+ alert.record_send_success!
108
+ @sent += 1
109
+ else
110
+ @logger.error "Email sending failed"
111
+ end
110
112
 
111
- # returns a Mail object
112
- def prepare_email(opts = {})
113
- from = opts[:from]
114
- reply_to = opts[:reply_to]
115
- to = opts[:to]
116
- message_id = opts[:message_id]
117
- alert = opts[:alert]
113
+ @logger.debug "Email response: #{response.inspect}"
118
114
 
119
- message_type = alert.rollup ? 'rollup' : 'alert'
115
+ rescue => e
116
+ @logger.error "Error generating or delivering email to #{alert.address}: #{e.class}: #{e.message}"
117
+ @logger.error e.backtrace.join("\n")
118
+ raise
119
+ end
120
120
 
121
- mydir = File.dirname(__FILE__)
122
- subject_template_path = case
123
- when @config.has_key?('templates') && @config['templates']["#{message_type}_subject.text"]
124
- @config['templates']["#{message_type}_subject.text"]
125
- else
126
- mydir + "/email/#{message_type}_subject.text.erb"
127
- end
128
- text_template_path = case
129
- when @config.has_key?('templates') && @config['templates']["#{message_type}.text"]
130
- @config['templates']["#{message_type}.text"]
131
- else
132
- mydir + "/email/#{message_type}.text.erb"
133
- end
134
- html_template_path = case
135
- when @config.has_key?('templates') && @config['templates']["#{message_type}.html"]
136
- @config['templates']["#{message_type}.html"]
137
- else
138
- mydir + "/email/#{message_type}.html.erb"
139
- end
140
- subject_template = ERB.new(File.read(subject_template_path), nil, '-')
141
- text_template = ERB.new(File.read(text_template_path), nil, '-')
142
- html_template = ERB.new(File.read(html_template_path), nil, '-')
121
+ private
143
122
 
144
- @alert = alert
145
- bnd = binding
123
+ # returns a Mail object
124
+ def prepare_email(opts = {})
125
+ from = opts[:from]
126
+ reply_to = opts[:reply_to]
127
+ to = opts[:to]
128
+ message_id = opts[:message_id]
129
+ alert = opts[:alert]
146
130
 
147
- # do some intelligence gathering in case an ERB execution blows up
148
- begin
149
- erb_to_be_executed = subject_template_path
150
- subject = subject_template.result(bnd).chomp
131
+ message_type = alert.rollup ? 'rollup' : 'alert'
151
132
 
152
- erb_to_be_executed = text_template_path
153
- body_text = text_template.result(bnd)
133
+ mydir = File.dirname(__FILE__)
134
+ subject_template_path = case
135
+ when @config.has_key?('templates') && @config['templates']["#{message_type}_subject.text"]
136
+ @config['templates']["#{message_type}_subject.text"]
137
+ else
138
+ mydir + "/email/#{message_type}_subject.text.erb"
139
+ end
140
+ text_template_path = case
141
+ when @config.has_key?('templates') && @config['templates']["#{message_type}.text"]
142
+ @config['templates']["#{message_type}.text"]
143
+ else
144
+ mydir + "/email/#{message_type}.text.erb"
145
+ end
146
+ html_template_path = case
147
+ when @config.has_key?('templates') && @config['templates']["#{message_type}.html"]
148
+ @config['templates']["#{message_type}.html"]
149
+ else
150
+ mydir + "/email/#{message_type}.html.erb"
151
+ end
152
+ subject_template = ERB.new(File.read(subject_template_path), nil, '-')
153
+ text_template = ERB.new(File.read(text_template_path), nil, '-')
154
+ html_template = ERB.new(File.read(html_template_path), nil, '-')
154
155
 
155
- erb_to_be_executed = html_template_path
156
- body_html = html_template.result(bnd)
157
- rescue => e
158
- @logger.error "Error while excuting ERBs for an email: " +
159
- "ERB being executed: #{erb_to_be_executed}"
160
- raise
161
- end
156
+ @alert = alert
157
+ bnd = binding
158
+
159
+ # do some intelligence gathering in case an ERB execution blows up
160
+ begin
161
+ erb_to_be_executed = subject_template_path
162
+ subject = subject_template.result(bnd).chomp
162
163
 
163
- @logger.debug("preparing email to: #{to}, subject: #{subject}, message-id: #{message_id}")
164
+ erb_to_be_executed = text_template_path
165
+ body_text = text_template.result(bnd)
164
166
 
165
- mail = Mail.new do
166
- from from
167
- to to
168
- subject subject
169
- reply_to reply_to
170
- message_id message_id
167
+ erb_to_be_executed = html_template_path
168
+ body_html = html_template.result(bnd)
169
+ rescue => e
170
+ @logger.error "Error while excuting ERBs for an email: " +
171
+ "ERB being executed: #{erb_to_be_executed}"
172
+ raise
173
+ end
171
174
 
172
- text_part do
173
- body body_text
174
- end
175
+ @logger.debug("preparing email to: #{to}, subject: #{subject}, message-id: #{message_id}")
175
176
 
176
- html_part do
177
- content_type 'text/html; charset=UTF-8'
178
- body body_html
179
- end
177
+ mail = Mail.new do
178
+ from from
179
+ to to
180
+ subject subject
181
+ reply_to reply_to
182
+ message_id message_id
183
+
184
+ text_part do
185
+ body body_text
180
186
  end
181
187
 
188
+ html_part do
189
+ content_type 'text/html; charset=UTF-8'
190
+ body body_html
191
+ end
182
192
  end
183
- end
184
193
 
194
+ end
185
195
  end
186
196
  end
187
197
  end