#! /usr/local/bin/ruby # Copyright (c) 2006 Frédéric Senault. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of the author or any contributors may be used to # endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # This collecter can be used instead of Nagios - just launch ntest from # the crontab, and you're set. # # It may operate with three kind of data collecting programs : # - those who are to be launched at every iteratop, # - those who open for append and immediately close the data files # - those who can receive a signal to rotate the files themselves # # The following config keys are read from ngraph.conf (lists are # space delimited) : # - gfc_pids : a list of pid files of processes to be signalled ; # optionnaly a signal (in the uppercase named form - i.e. SIGUSR) # may be added in parentheses after the filename ; by default a # SIGHUP is fired. # - gfc_run : a list of processes to launch ; they are simply # shelled, without care for any return status or output. # - gfc_files : the list of files to read line by line. # - gfc_sleep : the time to wait once all the processes are launched # and / or signalled ; default is two seconds. # # The performance data read from the files is based on Nagios # perfdata files : # # unix_time||host||address||service||result||perfdata||command # # Of those, only the time and the perfdata are really mandatory ; host # is used too, buy may be overriden. class GenericFileCollecter < Collecter def initialize() if($conf.has_key?(:gfc_pids)) then $conf[:gfc_pids].scan(/([a-zA-Z0-9._\/-]+)(?:\(([A-Z0-9]+)\))?/) do |pidf, sig| sig ||= 'HUP' begin pid = IO.read(pidf) Process.kill(sig, pid.to_i) if(pid) rescue Exception end end end if($conf.has_key?(:gfc_run)) then $conf[:gfc_run].scan(/([^ ]+)/) do |cmd| begin `#{cmd}` puts "#{cmd} : #{$?.exitcode}" if($?.exitcode != 0) rescue Exception end end end sleep(($conf.has_key?(:gfc_sleep) ? $conf[:gfc_sleep] : 2)) end def each() return unless($conf.has_key?(:gfc_files)) $conf[:gfc_files].split(/ /).each do |f| if(File.exists? f) then File.rename(f, f + '.old') File.open(f + '.old') do |h| h.each do |l| l.chomp! yield(GenericServiceData.new(l)) unless(l == '') end end end end end end class GenericServiceData < NGraphData attr_reader :address, :service, :result, :command def initialize(lgn) (@time, @host, @address, @service, @result, @perfdata, @command) = \ lgn.split(/\|\|/) @time = @time.to_i end def short() @host + '/' + @service end end