On Sat, 19 Aug 2006 14:17:11 -0400, Bob Norfolk  
<punkrockgeekboy / yahoo.com> wrote:

> I'm working on a ruby script to read Nagios's status.dat and output it's
> data.
Bob,

See if this works for you.

Regards,
   JJ

#
# Copyright 2006, by John Johnson, All Rights Reserved
# Released under the NewBSD license.
#

require 'ostruct'
require 'pp'

class Services < Hash

   SERVER_RE = /^\s*service\s*\{(.+?)\n\s*\}\s*$/m
   VALUE_RE = /^\s*([^=]+)\s*=\s*([^\n=]*?)$/
   INTEGER_RE = /^([-+]?\d+)$/
   FLOAT_RE = /^([-+]?\d*\.\d*[eE]?\d*)$/
   BOOLEAN_TRUE_RE = /^[1tTyY]+/ # e.g. 1, true, True, yes, Yes

   # Types of declarations possible for field names.
   :FIELD_NAMES
   :FIELD_REGULAR_EXPRESSIONS

   #
   # Conversion for field values.
   #
   NAME_TYPES = 0
   NAMES = 1
   CONVERSION_BLOCK = 2
   CONVERSIONS = [

     # The following fields have time values that are the number
     # of seconds past the epoch.
     [
       # Types of names listed.
       [ :FIELD_NAMES ],
       # Field name declarations.
       ['last_state_change', 'last_hard_state_change',
       'last_time_ok', 'last_time_warning', 'last_time_unknown',
       'last_time_critical', 'last_check', 'next_check',
       'last_notification', 'next_notification', 'last_update'],
       # Code to convert from a String to whatever this is.
       lambda { |seconds_string|
         return Time.at(seconds_string.to_i)
       }
     ],

     # The following appear to be boolean fields.
     [
       [ :FIELD_NAMES, :FIELD_REGULAR_EXPRESSIONS ],
       ['modified_attributes', 'has_been_checked', 'should_be_scheduled',
         'no_more_notifications',
         /\w+_enabled$/, # all field names ending in _enabled
         'problem_has_been_acknowledged', 'process_performance_data',
         'obsess_over_service', 'is_flapping'],
         lambda { |boolean_string|
           if boolean_string =~ BOOLEAN_TRUE_RE
             true
           else
             false
           end
         }
     ]
   ]

   HOST_NAME_PROPERTY = 'host_name'

   def convert_field(name, value)
     CONVERSIONS.each { |conv_set|
       name_types = conv_set[NAME_TYPES]
       names = conv_set[NAMES]
       conversion_block = conv_set[CONVERSION_BLOCK]

       if name_types.include?(:FIELD_REGULAR_EXPRESSIONS)
         names.each { |name_dec|
           case
           when name_dec.class==String
             if name == name_dec
               return conversion_block.call(value)
             end
           when name_dec.class==Regexp
             if name =~ name_dec
               return conversion_block.call(value)
             end
           else
             fail "Don't know what a #{name_dec.class} field name is"
           end
         }
       end
       if name_types.include?(:FIELD_NAMES)
         if names.include?(name)
           return conversion_block.call(value)
         end
       end
     }

     # Try implicit conversions.
     case value
     when INTEGER_RE
       return Integer(value)
     when FLOAT_RE
       return Float(value)
     end

     return String(value)
   end

   def initialize(filename)
     super
     contents = File.open(filename).read
     contents.scan(SERVER_RE) { |value_ary|
       values = value_ary[0]
       host_name = ""
       service = OpenStruct.new
       values.scan(VALUE_RE) { |name, value|
         converted = convert_field(name, value)
         dumped = Marshal.dump(converted)
         service.instance_eval(
           "self.#{name} = Marshal.load('#{dumped}')")
         host_name=value if name == HOST_NAME_PROPERTY
       }
       self[host_name] = service
     }
   end
end

services = Services.new('nagio.txt')
services.each_pair{ |service, properties|
   puts "Host: #{service}"
   puts "\t     has_been_checked: #{properties.has_been_checked}"
   puts "\t           next_check: #{properties.next_check}"
   puts "\tnotifications_enabled: #{properties.notifications_enabled}"
}

if services['www.bob.com'].obsess_over_service
   puts "Someone is obsessing over Bob!"
else
   puts "No one is obsessing over Bob."
end

if services['www.test.com'].obsess_over_service
   puts "Someone is obsessing over Test!"
else
   puts "No one is obsessing over Test."
end


-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/