Class: NagiosHerald::Formatter

Inherits:
Object
  • Object
show all
Includes:
Logging, Util
Defined in:
lib/nagios-herald/formatters/base.rb,
lib/nagios-herald/formatters/example.rb,
lib/nagios-herald/formatters/check_cpu.rb,
lib/nagios-herald/formatters/check_disk.rb,
lib/nagios-herald/formatters/check_memory.rb,
lib/nagios-herald/formatters/check_logstash.rb,
lib/nagios-herald/formatters/check_graphite_graph.rb

Defined Under Namespace

Classes: CheckCpu, CheckDisk, CheckGraphiteGraph, CheckLogstash, CheckMemory, Example

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Util

#get_nagios_var, get_script_path, load_helper, underscore_to_camel_case, #unescape_text

Methods included from Logging

#configure_logger_for, #logger, #logger_for

Constructor Details

#initialize(options) ⇒ Formatter

Returns a new instance of Formatter.



28
29
30
31
32
33
34
35
36
37
38
# File 'lib/nagios-herald/formatters/base.rb', line 28

def initialize(options)
  @content = Hash.new{ |h,k| h[k] = Hash.new(&h.default_proc) } # autovivify
  @content[:attachments] = []
  @content[:html]
  @content[:subject] = ""
  @content[:text]
  @nagios_url = options[:nagios_url]
  @sandbox  = get_sandbox_path
  @state_type = get_nagios_var("NAGIOS_SERVICESTATE") != "" ? "SERVICE" : "HOST"

end

Instance Attribute Details

#contentObject

all the content required to generate a message



24
25
26
# File 'lib/nagios-herald/formatters/base.rb', line 24

def content
  @content
end

#sandboxObject

Returns the value of attribute sandbox.



25
26
27
# File 'lib/nagios-herald/formatters/base.rb', line 25

def sandbox
  @sandbox
end

#state_typeObject

Returns the value of attribute state_type.



26
27
28
# File 'lib/nagios-herald/formatters/base.rb', line 26

def state_type
  @state_type
end

Class Method Details

.formattersObject



40
41
42
# File 'lib/nagios-herald/formatters/base.rb', line 40

def self.formatters
  @@formatters ||= {}
end

.inherited(subclass) ⇒ Object

Public: When subclassed formatters are instantiated, add them to the @@formatters hash. The key is the downcased and snake_cased name of the class file (i.e. check_disk); the value is the actual class (i.e. CheckDisk) so that we can easily instantiate formatters when we know the formatter name. Learned this pattern thanks to the folks at Chef and @jonlives. See github.com/opscode/chef/blob/11-stable/lib/chef/knife.rb#L79#L83

Returns the formatters hash.



52
53
54
55
56
57
58
# File 'lib/nagios-herald/formatters/base.rb', line 52

def self.inherited(subclass)
  subclass_base_name = subclass.name.split('::').last
  subclass_base_name.gsub!(/[A-Z]/) { |s| "_" + s } # replace uppercase with underscore and lowercase
  subclass_base_name.downcase!
  subclass_base_name.sub!(/^_/, "")   # strip the leading underscore
  formatters[subclass_base_name] = subclass
end

Instance Method Details

#ack_infoObject

Public: Formats the information about who ack’d the alert and when Generates text and HTML output.



290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/nagios-herald/formatters/base.rb', line 290

def ack_info
  section = __method__
  text = ""
  html = ""
  date = get_nagios_var("NAGIOS_LONGDATETIME")
  author = get_nagios_var("NAGIOS_#{@state_type}ACKAUTHOR")
  comment = get_nagios_var("NAGIOS_#{@state_type}ACKCOMMENT")
  hostname = get_nagios_var("NAGIOS_HOSTNAME")

  text += "At #{date} #{author}"
  html += "At #{date} #{author}"

  if @state_type == "SERVICE"
    desc = get_nagios_var("NAGIOS_SERVICEDESC")
    text += " acknowledged #{hostname}/#{desc}.\n\n"
    html += " acknowledged #{hostname}/#{desc}.<br><br>"
  else
    text += " acknowledged #{hostname}.\n\n"
    html += " acknowledged #{hostname}.<br><br>"

  end
  text += "Comment: #{comment}" if comment
  html += "Comment: #{comment}" if comment
  add_text(section, text)
  add_html(section, html)
end

#action_urlObject

Public: Formats the action URL for this alert. Generates text and HTML output.



248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/nagios-herald/formatters/base.rb', line 248

def action_url
  section = __method__
  text = ""
  html = ""
  action_url = get_nagios_var("NAGIOS_#{@state_type}ACTIONURL")
  if !action_url.nil? and !action_url.empty?
    text += "Action URL: #{action_url}\n\n"
    html += "<b>Action URL</b>: #{action_url}<br><br>"
  end
  add_text(section, text)
  add_html(section, html)
end

#add_attachment(path) ⇒ Object

Public: Add an attachment’s path to an array.

path - The fully qualified path for a file attachment

Example:

add_attachment("/tmp/file-to-attach.txt")

Returns the array of attachment paths.



109
110
111
112
# File 'lib/nagios-herald/formatters/base.rb', line 109

def add_attachment(path)
  #@attachments << path
  @content[:attachments] << path
end

#add_html(section, html) ⇒ Object

Public: Concatenates HTML content.

section - The content section name whose HTML we’ll concatenate text - The HTML we want to concatenate

Example:

add_html("state_detail", "Service is somewhere in Kansas")

Returns the concatenated HTML for the given section.



90
91
92
93
94
95
96
97
98
# File 'lib/nagios-herald/formatters/base.rb', line 90

def add_html(section, html)
  # Ensure our key is a symbol, regardless if we're passed a string or symbol
  section = section.to_sym
  if @content[:html][section].nil? or @content[:html][section].empty?
    @content[:html][section] = html
  else
    @content[:html][section] += html
  end
end

#add_text(section, text) ⇒ Object

Public: Concatenates text content.

section - The content section name whose text we’ll concatenate text - The text we want to concatenate

Example:

add_text("state_detail", "Service is somewhere in Kansas")

Returns the concatenated HTML for the given section.



70
71
72
73
74
75
76
77
78
# File 'lib/nagios-herald/formatters/base.rb', line 70

def add_text(section, text)
  # Ensure our key is a symbol, regardless if we're passed a string or symbol
  section = section.to_sym
  if @content[:text][section].nil? or @content[:text][section].empty?
    @content[:text][section] = text
  else
    @content[:text][section] += text
  end
end

#additional_detailsObject

Public: Formats information provided plugin’s long output. Generates text and HTML output.



212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/nagios-herald/formatters/base.rb', line 212

def additional_details
  section = __method__
  text = ""
  html = ""
  long_output = get_nagios_var("NAGIOS_LONG#{@state_type}OUTPUT")
  if !long_output.nil? and !long_output.empty?
    text += "Additional Details: #{unescape_text(long_output)}\n"
    html += "<b>Additional Details</b>: <pre>#{unescape_text(long_output)}</pre><br><br>"
    add_text(section, text)
    add_html(section, html)
  end
end

#additional_infoObject

Public: Formats information provided plugin’s output. Generates text and HTML output.



197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/nagios-herald/formatters/base.rb', line 197

def additional_info
  section = __method__
  text = ""
  html = ""
  output = get_nagios_var("NAGIOS_#{@state_type}OUTPUT")
  if !output.nil? and !output.empty?
    text += "Additional Info: #{unescape_text(output)}\n\n"
    html += "<b>Additional Info</b>: #{output}<br><br>"
    add_text(section, text)
    add_html(section, html)
  end
end

#alert_ack_urlObject

Public: Formats the URI one can click to acknowledge an alert (i.e. in an email) Generates text and HTML output.



348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
# File 'lib/nagios-herald/formatters/base.rb', line 348

def alert_ack_url
  section = __method__
  text = ""
  html = ""
  hostname  = get_nagios_var("NAGIOS_HOSTNAME")
  service_desc = get_nagios_var("NAGIOS_SERVICEDESC")

  if service_desc != ""
    url = "#{@nagios_url}/nagios/cgi-bin/cmd.cgi?cmd_typ=34&host=#{hostname}&service=#{service_desc}"
  else
    url = "#{@nagios_url}/nagios/cgi-bin/cmd.cgi?cmd_typ=33&host=#{hostname}"
  end
  url = URI.escape(url)
  text += "Acknowledge this alert: #{url}\n"
  text += "Alternatively, reply to this message with the word 'ack' in the body to acknowledge the alert.\n"
  html += "Acknowledge this alert: #{url}<br>"
  html += "Alternatively, <b>reply</b> to this message with the word '<b><font color='green'>ack</font></b>' in the body to acknowledge the alert.<br>"
  add_text(section, text)
  add_html(section, html)
end

#clean_sandboxObject

Public: Does some housecleaning on the sandbox, if it exists.



518
519
520
# File 'lib/nagios-herald/formatters/base.rb', line 518

def clean_sandbox
  FileUtils.remove_entry @sandbox if File.directory?(@sandbox)
end

#end_section(section) ⇒ Object

Public: Ends a format section’s HTML <div> block.

section - The name of the section whose HTML we’ll start.

Example

start_section("additional_details")

Generates an ending HTML <div> tag.



403
404
405
# File 'lib/nagios-herald/formatters/base.rb', line 403

def end_section(section)
  add_html(section, "</div>")
end

#generate_ack_contentObject

Public: Generate content for ACKNOWLEGEMENT alerts



451
452
453
454
# File 'lib/nagios-herald/formatters/base.rb', line 451

def generate_ack_content
  generate_section("host_info")
  generate_section("ack_info")
end

#generate_content(nagios_notification_type) ⇒ Object

Public: Dispatch method to help generate content based on notification type.

nagios_notification_type - One of any valid Nagios notification types.

Example

generate_content("PROBLEM")


465
466
467
468
469
470
471
472
473
474
475
476
477
# File 'lib/nagios-herald/formatters/base.rb', line 465

def generate_content(nagios_notification_type)
  case nagios_notification_type
    when "PROBLEM", "FLAPPINGSTART"
      generate_problem_content
    when "RECOVERY", "FLAPPINGSTOP"
      generate_recovery_content
    when "ACKNOWLEDGEMENT"
      generate_ack_content
    else
      logger.fatal "Invalid Nagios notification type! Expecting something like PROBLEM or RECOVERY. We got #{nagios_notification_type}."
      exit 1
    end
end

#generate_message_contentObject

Public: Generates content body.

Call various formatting methods that each generate content for their given sections.



502
503
504
505
506
# File 'lib/nagios-herald/formatters/base.rb', line 502

def generate_message_content
    generate_subject
    nagios_notification_type = get_nagios_var('NAGIOS_NOTIFICATIONTYPE')
    generate_content(nagios_notification_type)
end

#generate_problem_contentObject

Public: Generate content for PROBLEM alerts.



426
427
428
429
430
431
432
433
434
435
436
# File 'lib/nagios-herald/formatters/base.rb', line 426

def generate_problem_content
  generate_section("host_info")
  generate_section("state_info")
  generate_section("additional_info")
  generate_section("action_url")
  generate_section("notes")
  generate_section("additional_details")
  generate_section("recipients_email_link")
  generate_section("notification_info")
  generate_section("alert_ack_url")
end

#generate_recovery_contentObject

Public: Generate content for RECOVERY alerts.



439
440
441
442
443
444
445
446
447
448
# File 'lib/nagios-herald/formatters/base.rb', line 439

def generate_recovery_content
  generate_section("host_info")
  generate_section("state_info", "color:green")
  generate_section("additional_info")
  generate_section("action_url")
  generate_section("notes")
  generate_section("additional_details")
  generate_section("recipients_email_link")
  generate_section("notification_info")
end

#generate_section(section, *section_style_args) ⇒ Object

Public: Wrapper for starting a format section, calling the format method, and ending the section.

section - The name of the section whose HTML we’ll start. *section_style_args - A list of style attributes to be used in the <div> block for the section.

Example:

generate_section("additional_info", "color:green", "font-weight:bold") - Color all text green and bold it
generate_section("additional_info") - Color all text green

Calls the relevant section method to generate content.



419
420
421
422
423
# File 'lib/nagios-herald/formatters/base.rb', line 419

def generate_section(section, *section_style_args)
  start_section(section, *section_style_args)
  self.send(section)
  end_section(section)
end

#generate_subjectObject

Public: Generates a subject.

Returns a subject.



482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
# File 'lib/nagios-herald/formatters/base.rb', line 482

def generate_subject
  hostname          = get_nagios_var("NAGIOS_HOSTNAME")
  service_desc      = get_nagios_var("NAGIOS_SERVICEDESC")
  notification_type = get_nagios_var("NAGIOS_NOTIFICATIONTYPE")
  state             = get_nagios_var("NAGIOS_#{@state_type}STATE")

  subject="#{hostname}"
  subject += "/#{service_desc}" if service_desc != ""

  if @state_type == "SERVICE"
    subject="#{notification_type} Service #{subject} is #{state}"
  else
    subject="#{notification_type} Host #{subject} is #{state}"
  end
  @content[:subject] = subject
end

#get_sandbox_pathObject

Public: Creates a temporary directory in which to create files used in attachments.

Returns the path to a temporary directory.



512
513
514
515
# File 'lib/nagios-herald/formatters/base.rb', line 512

def get_sandbox_path
  @sandbox = Dir.mktmpdir if @sandbox.nil?
  return @sandbox
end

#host_infoObject

Public: Formats the information about the host that’s being alerted on. Generates text and HTML output.



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/nagios-herald/formatters/base.rb', line 134

def host_info
  section = __method__
  text = ""
  html = ""
  notification_type = get_nagios_var("NAGIOS_NOTIFICATIONTYPE")
  hostname          = get_nagios_var("NAGIOS_HOSTNAME")
  service_desc      = get_nagios_var("NAGIOS_SERVICEDESC")
  text += "Host: #{hostname} "
  html += "<br><b>Host</b>: #{hostname} "
  if !service_desc.nil? and !service_desc.empty?
    text += "Service: #{service_desc}\n"
    html += "<b>Service</b>: #{service_desc}<br/>"
  else
    # we need a trailing newline if no service description
    line_break(section)
  end
  add_text(section, text)
  add_html(section, html)
  line_break(section)
end

#line_break(section) ⇒ Object

Public: Appends a newline in text and HTML format.

section - The content section name that needs the line break

Example

line_break(additional_info)

Appends text and HTML output to the appropriate sections in @content



127
128
129
130
# File 'lib/nagios-herald/formatters/base.rb', line 127

def line_break(section)
  add_text(section, "\n")
  add_html(section, "<br>")
end

#notesObject

Public: Formats the notes information for this alert. Generates text and HTML output.



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/nagios-herald/formatters/base.rb', line 227

def notes
  section = __method__
  text = ""
  html = ""
  notes = get_nagios_var("NAGIOS_#{@state_type}NOTES")
  if !notes.nil? and !notes.empty?
    text += "Notes: #{unescape_text(notes)}\n\n"
    html += "<b>Notes</b>: #{notes}<br><br>"
  end

  notes_url = get_nagios_var("NAGIOS_#{@state_type}NOTESURL")
  if !notes_url.nil? and !notes_url.empty?
    text += "Notes URL: #{notes_url}\n\n"
    html += "<b>Notes URL</b>: #{notes_url}<br><br>"
  end
  add_text(section, text)
  add_html(section, html)
end

#notification_infoObject

Public: Formats information about the notification. Provides information such as the date and notification number. Generates text and HTML output.



183
184
185
186
187
188
189
190
191
192
193
# File 'lib/nagios-herald/formatters/base.rb', line 183

def notification_info
  section = __method__
  text = ""
  html = ""
  date   = get_nagios_var("NAGIOS_LONGDATETIME")
  number = get_nagios_var("NAGIOS_NOTIFICATIONNUMBER")
  text += "Notification sent at: #{date} (notification number #{number})\n\n"
  html += "Notification sent at: #{date} (notification number #{number})<br><br>"
  add_text(section, text)
  add_html(section, html)
end

Public: Formats the email recipients and URIs Generates text and HTML output.



275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/nagios-herald/formatters/base.rb', line 275

def recipients_email_link
  section = __method__
  text = ""
  html = ""
  recipients = get_nagios_var("NAGIOS_NOTIFICATIONRECIPIENTS")
  return if recipients.nil?
  recipients_list = recipients.split(',')
  text += "Sent to #{recipients}\n\n"
  html += "Sent to #{recipients}<br><br>"
  add_text(section, text)
  add_html(section, html)
end

#short_ack_infoObject

Public: Formats brief ack information. Useful for pager messages. Generates text and HTML output.



320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
# File 'lib/nagios-herald/formatters/base.rb', line 320

def short_ack_info
  section = __method__
  text = ""
  html = ""
  author    = get_nagios_var("NAGIOS_#{@state_type}ACKAUTHOR")
  comment   = get_nagios_var("NAGIOS_#{@state_type}COMMENT")
  hostname  = get_nagios_var("NAGIOS_HOSTNAME")

  text += "#{author}  ack'd "
  html += "#{author}  ack'd "

  if @state_type == "SERVICE"
    desc = get_nagios_var("NAGIOS_SERVICEDESC")
    text += "#{desc} on #{hostname}.\n"
    html += "#{desc} on #{hostname}.<br>"
  else
    text += "#{hostname}.\n"
    html += "#{hostname}.<br>"

  end
  text += "Comment: #{comment}" if comment
  html += "Comment: #{comment}" if comment
  add_text(section, text)
  add_html(section, html)
end

#short_state_detailObject

FIXME: Looks like a dupe of #additional_info (used in pager alerts, it seems)



262
263
264
265
266
267
268
269
270
271
# File 'lib/nagios-herald/formatters/base.rb', line 262

def short_state_detail
  section = __method__
  text = ""
  html = ""
  output   = get_nagios_var("NAGIOS_#{@state_type}OUTPUT")
  text += "#{output}\n"
  html += "#{output}<br>"
  add_text(section, text)
  add_html(section, html)
end

#start_section(section, *section_style_args) ⇒ Object

Public: Starts a format section’s HTML <div> block.

section - The name of the section whose HTML we’ll start. *section_style_args - CSS-type attributes used to style the content.

Example

start_section("additional_details", "color:green")

Generates HTML <div> block with the requested style.



383
384
385
386
387
388
389
390
391
392
# File 'lib/nagios-herald/formatters/base.rb', line 383

def start_section(section, *section_style_args)
  html = ""
  if !section_style_args.nil?
    style = section_style_args.join(';')
    html += "<div style='#{style}'>"
  else
    html += "<div>"
  end
  add_html(section, html)
end

#state_infoObject

Public: Formats information about the state of the thing being alerted on where ‘thing’ is either HOST or SERVICE. Generates text and HTML output.



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/nagios-herald/formatters/base.rb', line 158

def state_info
  section = __method__
  text = ""
  html = ""
  state         = get_nagios_var("NAGIOS_#{@state_type}STATE")
  duration      = get_nagios_var("NAGIOS_#{@state_type}DURATION")
  last_duration = get_nagios_var("NAGIOS_LAST#{@state_type}STATE")
  attempts      = get_nagios_var("NAGIOS_#{@state_type}ATTEMPT")
  max_attempts  = get_nagios_var("NAGIOS_MAX#{@state_type}ATTEMPTS")

  text += "State is now: #{state} for #{duration} (was #{last_duration}) after #{attempts} / #{max_attempts} checks\n"

  if state.eql? 'OK' or state.eql? 'UP'
      html += "State is now: <b>#{state}</b> for <b>#{duration}</b> (was #{last_duration}) after <b>#{attempts} / #{max_attempts}</b> checks<br/>"
  else
      html += "State is now: <b><font style='color:red'>#{state}</font></b> for <b>#{duration}</b> (was #{last_duration}) after <b>#{attempts} / #{max_attempts}</b> checks<br/>"
  end
  add_text(section, text)
  add_html(section, html)
  line_break(section)
end