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
@@ -25,7 +25,7 @@ module Flapjack
25
25
  raise "Redis connection not set" unless redis = options[:redis]
26
26
 
27
27
  redis.keys('contact:*').inject([]) {|ret, k|
28
- k =~ /^contact:(\d+)$/
28
+ k =~ /^contact:(.*)$/
29
29
  id = $1
30
30
  contact = self.find_by_id(id, :redis => redis)
31
31
  ret << contact if contact
@@ -129,6 +129,12 @@ module Flapjack
129
129
  merge('service_key' => service_key)
130
130
  end
131
131
 
132
+ def set_pagerduty_credentials(details)
133
+ @redis.hset("contact_media:#{self.id}", 'pagerduty', details['service_key'])
134
+ @redis.hmset("contact_pagerduty:#{self.id}",
135
+ *['subdomain', 'username', 'password'].collect {|f| [f, details[f]]})
136
+ end
137
+
132
138
  # NB ideally contacts_for:* keys would scope the entity and check by an
133
139
  # input source, for namespacing purposes
134
140
  def entities(options = {})
@@ -211,6 +217,7 @@ module Flapjack
211
217
  end
212
218
 
213
219
  def set_interval_for_media(media, interval)
220
+ return if 'pagerduty'.eql?(media)
214
221
  if interval.nil?
215
222
  @redis.hdel("contact_media_intervals:#{self.id}", media)
216
223
  return
@@ -225,6 +232,7 @@ module Flapjack
225
232
  end
226
233
 
227
234
  def set_rollup_threshold_for_media(media, threshold)
235
+ return if 'pagerduty'.eql?(media)
228
236
  if threshold.nil?
229
237
  @redis.hdel("contact_media_rollup_thresholds:#{self.id}", media)
230
238
  return
@@ -234,12 +242,8 @@ module Flapjack
234
242
  end
235
243
 
236
244
  def set_address_for_media(media, address)
245
+ return if 'pagerduty'.eql?(media)
237
246
  @redis.hset("contact_media:#{self.id}", media, address)
238
- if media == 'pagerduty'
239
- # FIXME - work out what to do when changing the pagerduty service key (address)
240
- # probably best solution is to remove the need to have the username and password
241
- # and subdomain as pagerduty's updated api's mean we don't them anymore I think...
242
- end
243
247
  self.media = @redis.hgetall("contact_media:#{@id}")
244
248
  end
245
249
 
@@ -312,10 +316,13 @@ module Flapjack
312
316
  key = "contact_alerting_checks:#{self.id}:media:#{media}"
313
317
  cleaned = 0
314
318
  alerting_checks_for_media(media).each do |check|
319
+ entity_check = Flapjack::Data::EntityCheck.for_event_id(check, :redis => @redis)
315
320
  next unless Flapjack::Data::EntityCheck.state_for_event_id?(check, :redis => @redis) == 'ok' ||
316
321
  Flapjack::Data::EntityCheck.in_unscheduled_maintenance_for_event_id?(check, :redis => @redis) ||
317
- Flapjack::Data::EntityCheck.in_scheduled_maintenance_for_event_id?(check, :redis => @redis)
322
+ Flapjack::Data::EntityCheck.in_scheduled_maintenance_for_event_id?(check, :redis => @redis) ||
323
+ !entity_check.contacts.map {|c| c.id}.include?(self.id)
318
324
 
325
+ # FIXME: why can't i get this logging when called from notifier (notification.rb)?
319
326
  @logger.debug("removing from alerting checks for #{self.id}/#{media}: #{check}") if @logger
320
327
  remove_alerting_check_for_media(media, check)
321
328
  cleaned += 1
@@ -30,9 +30,10 @@ module Flapjack
30
30
  # TODO probably shouldn't always be creating on query -- work out when this should be happening
31
31
  def self.for_event_id(event_id, options = {})
32
32
  raise "Redis connection not set" unless redis = options[:redis]
33
+ logger = options[:logger]
33
34
  entity_name, check = event_id.split(':', 2)
34
- self.new(Flapjack::Data::Entity.find_by_name(entity_name, :redis => redis, :create => true), check,
35
- :redis => redis)
35
+ self.new(Flapjack::Data::Entity.find_by_name(entity_name, :redis => redis, :create => true, :logger => true), check,
36
+ :redis => redis, :logger => logger)
36
37
  end
37
38
 
38
39
  # TODO probably shouldn't always be creating on query -- work out when this should be happening
@@ -533,7 +534,7 @@ module Flapjack
533
534
  end
534
535
 
535
536
  entity.contacts + contact_ids.collect {|c_id|
536
- Flapjack::Data::Contact.find_by_id(c_id, :redis => @redis)
537
+ Flapjack::Data::Contact.find_by_id(c_id, :redis => @redis, :logger => @logger)
537
538
  }.compact
538
539
  end
539
540
 
@@ -61,10 +61,8 @@ module Flapjack
61
61
  'last_state' => last_state[:state],
62
62
  'last_summary' => last_state[:summary],
63
63
  'state_duration' => opts[:state_duration],
64
-
65
64
  'type' => opts[:type] || type_for_event(event),
66
65
  'severity' => opts[:severity],
67
-
68
66
  'tags' => tag_data }
69
67
 
70
68
  redis.rpush(queue, Oj.dump(notif))
@@ -94,11 +92,15 @@ module Flapjack
94
92
  end
95
93
 
96
94
  def ok?
97
- @state && ['ok', 'up'].include?(@state.downcase)
95
+ @state && ['ok', 'up'].include?(@state)
98
96
  end
99
97
 
100
98
  def acknowledgement?
101
- @state && ['acknowledgement'].include?(@state.downcase)
99
+ @state && ['acknowledgement'].include?(@state)
100
+ end
101
+
102
+ def test?
103
+ @state && ['test_notifications'].include?(@state)
102
104
  end
103
105
 
104
106
  def contents
@@ -123,7 +125,7 @@ module Flapjack
123
125
  default_timezone = opts[:default_timezone]
124
126
  logger = opts[:logger]
125
127
 
126
- @messages ||= contacts.collect {|contact|
128
+ @messages ||= contacts.collect do |contact|
127
129
  contact_id = contact.id
128
130
  rules = contact.notification_rules
129
131
  media = contact.media
@@ -195,36 +197,39 @@ module Flapjack
195
197
  logger.debug "media_to_use: #{media_to_use}"
196
198
 
197
199
  # here begins rollup madness
198
- media_to_use.each_pair.inject([]) { |ret, (media, address)|
200
+ media_to_use.each_pair.inject([]) do |ret, (media, address)|
199
201
  rollup_type = nil
200
202
 
201
- contact.add_alerting_check_for_media(media, @event_id) unless ok? || acknowledgement?
203
+ contact.add_alerting_check_for_media(media, @event_id) unless ok? || acknowledgement? || test?
202
204
 
203
205
  # expunge checks in (un)scheduled maintenance from the alerting set
204
206
  cleaned = contact.clean_alerting_checks_for_media(media)
205
207
  logger.debug("cleaned alerting checks for #{media}: #{cleaned}")
206
208
 
207
- alerting_checks = contact.count_alerting_checks_for_media(media)
208
- rollup_threshold = contact.rollup_threshold_for_media(media)
209
- case
210
- when rollup_threshold.nil?
211
- # back away slowly
212
- when alerting_checks >= rollup_threshold
213
- next ret if contact.drop_rollup_notifications_for_media?(media)
214
- contact.update_sent_rollup_alert_keys_for_media(media, :delete => ok?)
215
- rollup_type = 'problem'
216
- when (alerting_checks + cleaned >= rollup_threshold)
217
- # alerting checks was just cleaned such that it is now below the rollup threshold
218
- rollup_type = 'recovery'
209
+ # pagerduty is an example of a medium which should never be rolled up
210
+ unless ['pagerduty'].include?(media)
211
+ alerting_checks = contact.count_alerting_checks_for_media(media)
212
+ rollup_threshold = contact.rollup_threshold_for_media(media)
213
+ case
214
+ when rollup_threshold.nil?
215
+ # back away slowly
216
+ when alerting_checks >= rollup_threshold
217
+ next ret if contact.drop_rollup_notifications_for_media?(media)
218
+ contact.update_sent_rollup_alert_keys_for_media(media, :delete => ok?)
219
+ rollup_type = 'problem'
220
+ when (alerting_checks + cleaned >= rollup_threshold)
221
+ # alerting checks was just cleaned such that it is now below the rollup threshold
222
+ rollup_type = 'recovery'
223
+ end
224
+ logger.debug "rollup decisions: #{@event_id} #{@state} #{media} #{address} rollup_type: #{rollup_type}"
219
225
  end
220
- logger.debug "rollup decisions: #{@event_id} #{@state} #{media} #{address} rollup_type: #{rollup_type}"
221
226
 
222
227
  m = Flapjack::Data::Message.for_contact(contact,
223
228
  :medium => media, :address => address, :rollup => rollup_type)
224
229
  ret << m
225
230
  ret
226
- }
227
- }.compact.flatten
231
+ end
232
+ end.compact.flatten # @messages ||= contacts.collect do ...
228
233
  end
229
234
 
230
235
  private
@@ -238,16 +243,12 @@ module Flapjack
238
243
  @time = opts['time']
239
244
  @count = opts['count']
240
245
  @duration = opts['duration']
241
-
242
246
  @last_state = opts['last_state']
243
247
  @last_summary = opts['last_summary']
244
248
  @state_duration = opts['state_duration']
245
-
246
249
  @type = opts['type']
247
250
  @severity = opts['severity']
248
-
249
- tags = opts['tags']
250
- @tags = tags.is_a?(Array) ? Flapjack::Data::TagSet.new(tags) : nil
251
+ @tags = opts['tags'].is_a?(Array) ? Flapjack::Data::TagSet.new(opts['tags']) : nil
251
252
  end
252
253
 
253
254
  # # time restrictions match?
@@ -97,8 +97,11 @@ module Flapjack
97
97
  # https://github.com/flpjck/flapjack/wiki/API#wiki-get_contacts
98
98
  app.get '/contacts' do
99
99
  content_type :json
100
-
101
- Flapjack::Data::Contact.all(:redis => redis).to_json
100
+ "[" +
101
+ Flapjack::Data::Contact.all(:redis => redis).map do |contact|
102
+ contact.to_json
103
+ end.join(',') +
104
+ "]"
102
105
  end
103
106
 
104
107
  # Returns the core information about the specified contact
@@ -233,19 +236,36 @@ module Flapjack
233
236
 
234
237
  contact = find_contact(params[:contact_id])
235
238
  errors = []
236
- if params[:address].nil?
237
- errors << "no address for '#{params[:id]}' media"
238
- end
239
239
 
240
- halt err(403, *errors) unless errors.empty?
240
+ if 'pagerduty'.eql?(params[:id])
241
+ errors = [:service_key, :subdomain, :username, :password].inject([]) do |memo, pdp|
242
+ memo << "no #{pdp.to_s} for 'pagerduty' media" if params[pdp].nil?
243
+ memo
244
+ end
245
+
246
+ halt err(403, *errors) unless errors.empty?
247
+
248
+ contact.set_pagerduty_credentials('service_key' => params[:service_key],
249
+ 'subdomain' => params[:subdomain],
250
+ 'username' => params[:username],
251
+ 'password' => params[:password])
241
252
 
242
- contact.set_address_for_media(params[:id], params[:address])
243
- contact.set_interval_for_media(params[:id], params[:interval])
244
- contact.set_rollup_threshold_for_media(params[:id], params[:rollup_threshold])
253
+ contact.pagerduty_credentials.to_json
254
+ else
255
+ if params[:address].nil?
256
+ errors << "no address for '#{params[:id]}' media"
257
+ end
258
+
259
+ halt err(403, *errors) unless errors.empty?
245
260
 
246
- {'address' => contact.media[params[:id]],
247
- 'interval' => contact.media_intervals[params[:id]],
248
- 'rollup_threshold' => contact.media_rollup_thresholds[params[:id]]}.to_json
261
+ contact.set_address_for_media(params[:id], params[:address])
262
+ contact.set_interval_for_media(params[:id], params[:interval])
263
+ contact.set_rollup_threshold_for_media(params[:id], params[:rollup_threshold])
264
+
265
+ {'address' => contact.media[params[:id]],
266
+ 'interval' => contact.media_intervals[params[:id]],
267
+ 'rollup_threshold' => contact.media_rollup_thresholds[params[:id]]}.to_json
268
+ end
249
269
  end
250
270
 
251
271
  # delete a media of a contact
@@ -12,6 +12,7 @@ require 'em/protocols/smtpclient'
12
12
  require 'flapjack/utility'
13
13
 
14
14
  require 'flapjack/data/entity_check'
15
+ require 'flapjack/data/alert'
15
16
 
16
17
  module Flapjack
17
18
  module Gateways
@@ -31,46 +32,22 @@ module Flapjack
31
32
  end
32
33
 
33
34
  # TODO refactor to remove complexity
34
- def perform(notification)
35
- prepare( notification )
36
- deliver( notification )
35
+ def perform(contents)
36
+ @logger.debug "Woo, got an alert to send out: #{contents.inspect}"
37
+ alert = prepare(contents)
38
+ deliver(alert)
37
39
  end
38
40
 
39
41
  # sets a bunch of class instance variables for each email
40
- def prepare(notification)
41
- @logger.debug "Woo, got a notification to send out: #{notification.inspect}"
42
-
43
- # The instance variables are referenced by the templates, which
44
- # share the current binding context
45
- @notification_type = notification['notification_type']
46
- @notification_id = notification['id'] || SecureRandom.uuid
47
- @rollup = notification['rollup']
48
- @rollup_alerts = notification['rollup_alerts']
49
- @rollup_threshold = notification['rollup_threshold']
50
- @contact_first_name = notification['contact_first_name']
51
- @contact_last_name = notification['contact_last_name']
52
- @state = notification['state']
53
- @duration = notification['state_duration']
54
- @summary = notification['summary']
55
- @last_state = notification['last_state']
56
- @last_summary = notification['last_summary']
57
- @details = notification['details']
58
- @time = notification['time']
59
- @entity_name, @check = notification['event_id'].split(':', 2)
60
-
61
- entity_check = Flapjack::Data::EntityCheck.for_event_id(notification['event_id'],
62
- :redis => @redis)
63
-
64
- @in_unscheduled_maintenance = entity_check.in_scheduled_maintenance?
65
- @in_scheduled_maintenance = entity_check.in_unscheduled_maintenance?
66
-
42
+ def prepare(contents)
43
+ Flapjack::Data::Alert.new(contents, :logger => @logger)
67
44
  rescue => e
68
- @logger.error "Error preparing email to #{m_to}: #{e.class}: #{e.message}"
45
+ @logger.error "Error preparing email to #{contents['address']}: #{e.class}: #{e.message}"
69
46
  @logger.error e.backtrace.join("\n")
70
47
  raise
71
48
  end
72
49
 
73
- def deliver(notification)
50
+ def deliver(alert)
74
51
  host = @smtp_config ? @smtp_config['host'] : nil
75
52
  port = @smtp_config ? @smtp_config['port'] : nil
76
53
  starttls = @smtp_config ? !! @smtp_config['starttls'] : nil
@@ -85,21 +62,21 @@ module Flapjack
85
62
 
86
63
  m_from = "flapjack@#{@fqdn}"
87
64
  @logger.debug("flapjack_mailer: set from to #{m_from}")
88
- m_reply_to = m_from
89
- m_to = notification['address']
90
-
91
65
 
92
- mail = prepare_email(:from => m_from,
93
- :to => m_to)
66
+ mail = prepare_email(:from => m_from,
67
+ :to => alert.address,
68
+ :message_id => "<#{alert.notification_id}@#{@fqdn}>",
69
+ :alert => alert)
94
70
 
95
71
  smtp_args = {:from => m_from,
96
- :to => m_to,
72
+ :to => alert.address,
97
73
  :content => "#{mail.to_s}\r\n.\r\n",
98
74
  :domain => @fqdn,
99
75
  :host => host || 'localhost',
100
76
  :port => port || 25,
101
77
  :starttls => starttls}
102
78
  smtp_args.merge!(:auth => auth) if auth
79
+
103
80
  email = EM::P::SmtpClient.send(smtp_args)
104
81
 
105
82
  response = EM::Synchrony.sync(email)
@@ -107,45 +84,64 @@ module Flapjack
107
84
  # http://tools.ietf.org/html/rfc821#page-36 SMTP response codes
108
85
  if response && response.respond_to?(:code) &&
109
86
  ((response.code == 250) || (response.code == 251))
110
- @logger.info "Email sending succeeded"
87
+ alert.record_send_success!
111
88
  @sent += 1
112
89
  else
113
90
  @logger.error "Email sending failed"
114
91
  end
115
92
 
116
- @logger.info "Email response: #{response.inspect}"
93
+ @logger.debug "Email response: #{response.inspect}"
117
94
 
118
95
  rescue => e
119
- @logger.error "Error delivering email to #{m_to}: #{e.class}: #{e.message}"
96
+ @logger.error "Error generating or delivering email to #{alert.address}: #{e.class}: #{e.message}"
120
97
  @logger.error e.backtrace.join("\n")
121
98
  raise
122
99
  end
123
100
 
124
101
  private
125
102
 
103
+ # returns a Mail object
126
104
  def prepare_email(opts = {})
127
105
  from = opts[:from]
128
106
  to = opts[:to]
129
- message_id = "<#{@notification_id}@#{@fqdn}>"
107
+ message_id = opts[:message_id]
108
+ alert = opts[:alert]
130
109
 
131
110
  message_type = case
132
- when @rollup
111
+ when alert.rollup
133
112
  'rollup'
134
113
  else
135
114
  'alert'
136
115
  end
137
116
 
138
- subject_template = ERB.new(File.read(File.dirname(__FILE__) +
139
- "/email/#{message_type}_subject.text.erb"), nil, '-')
117
+ mydir = File.dirname(__FILE__)
118
+
119
+ subject_template_path = mydir + "/email/#{message_type}_subject.text.erb"
120
+ text_template_path = mydir + "/email/#{message_type}.text.erb"
121
+ html_template_path = mydir + "/email/#{message_type}.html.erb"
140
122
 
141
- text_template = ERB.new(File.read(File.dirname(__FILE__) +
142
- "/email/#{message_type}.text.erb"), nil, '-')
123
+ subject_template = ERB.new(File.read(subject_template_path), nil, '-')
124
+ text_template = ERB.new(File.read(text_template_path), nil, '-')
125
+ html_template = ERB.new(File.read(html_template_path), nil, '-')
143
126
 
144
- html_template = ERB.new(File.read(File.dirname(__FILE__) +
145
- "/email/#{message_type}.html.erb"), nil, '-')
127
+ @alert = alert
128
+ bnd = binding
146
129
 
147
- bnd = binding
148
- subject = subject_template.result(bnd).chomp
130
+ # do some intelligence gathering in case an ERB execution blows up
131
+ begin
132
+ erb_to_be_executed = subject_template_path
133
+ subject = subject_template.result(bnd).chomp
134
+
135
+ erb_to_be_executed = text_template_path
136
+ body_text = text_template.result(bnd)
137
+
138
+ erb_to_be_executed = html_template_path
139
+ body_html = html_template.result(bnd)
140
+ rescue => e
141
+ @logger.error "Error while excuting ERBs for an email: " +
142
+ "ERB being executed: #{erb_to_be_executed}"
143
+ raise
144
+ end
149
145
 
150
146
  @logger.debug("preparing email to: #{to}, subject: #{subject}, message-id: #{message_id}")
151
147
 
@@ -157,12 +153,12 @@ module Flapjack
157
153
  message_id message_id
158
154
 
159
155
  text_part do
160
- body text_template.result(bnd)
156
+ body body_text
161
157
  end
162
158
 
163
159
  html_part do
164
160
  content_type 'text/html; charset=UTF-8'
165
- body html_template.result(bnd)
161
+ body body_html
166
162
  end
167
163
  end
168
164
 
@@ -11,7 +11,7 @@
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
16
  <p>Monitoring has detected the following:</p>
17
17
 
@@ -19,56 +19,56 @@
19
19
  <tbody>
20
20
  <tr>
21
21
  <td><strong>Entity</strong></td>
22
- <td><%= @entity_name %></td>
22
+ <td><%= @alert.entity %></td>
23
23
  </tr>
24
24
 
25
25
  <tr>
26
26
  <td><strong>Check</strong></td>
27
- <td><%= @check %></td>
27
+ <td><%= @alert.check %></td>
28
28
  </tr>
29
29
 
30
30
  <tr>
31
31
  <td><strong>State</strong></td>
32
- <td><%= ['ok'].include?(@state) ? @state.upcase : @state.titleize %></td>
32
+ <td><%= @alert.state_title_case %></td>
33
33
  </tr>
34
34
 
35
35
  <tr>
36
36
  <td><strong>Summary</strong></td>
37
- <td><%= @summary %></td>
37
+ <td><%= @alert.summary %></td>
38
38
  </tr>
39
39
 
40
- <% if @details %>
40
+ <% if @alert.details %>
41
41
  <tr>
42
42
  <td><strong>Details</strong></td>
43
- <td><%= @details %></td>
43
+ <td><%= @alert.details %></td>
44
44
  </tr>
45
45
  <% end %>
46
46
 
47
- <% if @time %>
47
+ <% if @alert.time %>
48
48
  <tr>
49
49
  <td><strong>Time</strong></td>
50
- <td><%= Time.at(@time.to_i).to_s %></td>
50
+ <td><%= Time.at(@alert.time.to_i).to_s %></td>
51
51
  </tr>
52
52
  <% end %>
53
53
 
54
- <% if @duration && @duration > 40 %>
54
+ <% if @alert.state_duration && @alert.state_duration > 40 %>
55
55
  <tr>
56
56
  <td><strong>Duration</strong></td>
57
- <td><%= ChronicDuration.output(@duration) %></td>
57
+ <td><%= ChronicDuration.output(@alert.state_duration) %></td>
58
58
  </tr>
59
59
  <% end %>
60
60
 
61
- <% if @last_state %>
61
+ <% if @alert.last_state %>
62
62
  <tr>
63
63
  <td><strong>Previous State</strong></td>
64
- <td><%= ['ok'].include?(@last_state) ? @last_state.upcase : @last_state.titleize %></td>
64
+ <td><%= @alert.last_state_title_case %></td>
65
65
  </tr>
66
66
  <% end %>
67
67
 
68
- <% if @last_summary %>
68
+ <% if @alert.last_summary %>
69
69
  <tr>
70
70
  <td><strong>Previous Summary</strong></td>
71
- <td><%= @last_summary %></td>
71
+ <td><%= @alert.last_summary %></td>
72
72
  </tr>
73
73
  <% end %>
74
74