packages: nagios-ocpd/README (NEW), nagios-ocpd/nagios-ocpd.spec (NEW), nag...

glen glen at pld-linux.org
Wed Aug 5 02:30:33 CEST 2009


Author: glen                         Date: Wed Aug  5 00:30:33 2009 GMT
Module: packages                      Tag: HEAD
---- Log message:
- new

---- Files affected:
packages/nagios-ocpd:
   README (NONE -> 1.1)  (NEW), nagios-ocpd.spec (NONE -> 1.1)  (NEW), ocpd.init (NONE -> 1.1)  (NEW), ocpd.pl (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: packages/nagios-ocpd/README
diff -u /dev/null packages/nagios-ocpd/README:1.1
--- /dev/null	Wed Aug  5 02:30:33 2009
+++ packages/nagios-ocpd/README	Wed Aug  5 02:30:27 2009
@@ -0,0 +1,28 @@
+On the slave Nagios box, you will first want to disable OSHP/OCSP as we're
+going to use a replacement processor using perfdata files. 
+ 
+obsess_over_hosts=0
+obsess_over_services=0
+
+ 
+Then you will require the following additional config: 
+ 
+# Enable Performance data processing.
+process_performance_data=1
+
+# Files to which Nagios will write data. In this setup
+# they will be named pipes.
+host_perfdata_file=/path/to/host-perfdata.fifo
+service_perfdata_file=/path/to/service-perfdata.fifo
+
+# This is exactly what will be sent to send_NSCA. Do not change it.
+host_perfdata_file_template=$HOSTNAME$\t$HOSTSTATEID$\t$HOSTOUTPUT$|$HOSTPERFDATA$
+service_perfdata_file_template=$HOSTNAME$\t$SERVICEDESC$\t$SERVICESTATEID$\t$SERVICEOUTPUT$|$SERVICEPERFDATA$
+
+# If using Nagios 2, use the 'w' mode
+host_perfdata_file_mode=p
+service_perfdata_file_mode=p
+
+# We don't want to process any command, so set this to 0
+host_perfdata_file_processing_interval=0
+service_perfdata_file_processing_interval=0

================================================================
Index: packages/nagios-ocpd/nagios-ocpd.spec
diff -u /dev/null packages/nagios-ocpd/nagios-ocpd.spec:1.1
--- /dev/null	Wed Aug  5 02:30:33 2009
+++ packages/nagios-ocpd/nagios-ocpd.spec	Wed Aug  5 02:30:27 2009
@@ -0,0 +1,90 @@
+# $Revision$, $Date$
+%include	/usr/lib/rpm/macros.perl
+Summary:	Obsessive Compulsive Host/Service Processor Daemon for Nagios
+Name:		nagios-ocpd
+Version:	1.0
+Release:	0.13
+License:	GPL v2+
+Group:		Networking/Daemons
+Source0:	ocpd.pl
+Source1:	README
+Source2:	ocpd.init
+URL:		http://wiki.nagios.org/index.php/OCP_Daemon
+BuildRequires:	perl-Event-Lib
+BuildRequires:	perl-base
+BuildRequires:	rpm-perlprov >= 4.1-13
+BuildRequires:	rpmbuild(macros) >= 1.228
+Requires(post,preun):	/sbin/chkconfig
+Requires:	nagios >= 3.1.2-6
+Requires:	nagios-nsca-client
+Requires:	perl-Event-Lib >= 1.03-1
+Requires:	rc-scripts
+BuildArch:	noarch
+BuildRoot:	%{tmpdir}/%{name}-%{version}-root-%(id -u -n)
+
+%define		_libdir		%{_prefix}/lib/nagios
+%define		_spooldir	%{_var}/spool/nagios
+
+%description
+Given the way Nagios operates, running a command every time a
+host/service check result comes in can greatly reduce the speed at
+which Nagios can do its work. On huge Nagios setups the checks can end
+up lagging behind without fully using the server resources.
+
+There is a way to make Nagios write OCHP/OCSP data into a named pipe
+instead of running a command every time, and on the other end of the
+pipe a daemon takes care of sending the data to the master Nagios
+server.
+
+%prep
+%setup -qcT
+install %{SOURCE0} .
+cp %{SOURCE1} .
+
+%build
+%{__perl} -c ocpd.pl
+
+%install
+rm -rf $RPM_BUILD_ROOT
+install -d $RPM_BUILD_ROOT{%{_libdir},%{_spooldir},/etc/rc.d/init.d}
+install ocpd.pl $RPM_BUILD_ROOT%{_libdir}/ocpd
+touch $RPM_BUILD_ROOT%{_spooldir}/host-perfdata.fifo
+touch $RPM_BUILD_ROOT%{_spooldir}/service-perfdata.fifo
+install %{SOURCE2} $RPM_BUILD_ROOT/etc/rc.d/init.d/%{name}
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post
+for f in service-perfdata.fifo host-perfdata.fifo; do
+	if [ ! -e %{_spooldir}/$f ]; then
+		mkfifo -m 600 %{_spooldir}/$f
+		chown nagios:nagios %{_spooldir}/$f
+	fi
+done
+
+/sbin/chkconfig --add %{name}
+%service %{name} restart
+
+%preun
+if [ "$1" = "0" ]; then
+	%service -q %{name} stop
+	/sbin/chkconfig --del %{name}
+fi
+
+%files
+%defattr(644,root,root,755)
+%doc README
+%attr(754,root,root) /etc/rc.d/init.d/nagios-ocpd
+%attr(755,root,root) %{_libdir}/ocpd
+%attr(600,nagios,nagios) %ghost %{_spooldir}/host-perfdata.fifo
+%attr(600,nagios,nagios) %ghost %{_spooldir}/service-perfdata.fifo
+
+%define date	%(echo `LC_ALL="C" date +"%a %b %d %Y"`)
+%changelog
+* %{date} PLD Team <feedback at pld-linux.org>
+All persons listed below can be reached at <cvs_login>@pld-linux.org
+
+$Log$
+Revision 1.1  2009/08/05 00:30:27  glen
+- new

================================================================
Index: packages/nagios-ocpd/ocpd.init
diff -u /dev/null packages/nagios-ocpd/ocpd.init:1.1
--- /dev/null	Wed Aug  5 02:30:33 2009
+++ packages/nagios-ocpd/ocpd.init	Wed Aug  5 02:30:27 2009
@@ -0,0 +1,197 @@
+#!/bin/sh
+#
+# ocpd	Obsessive Compulsive Host/Service Processor Daemon for Nagios
+#
+# chkconfig:	345 84 26
+#
+# description:	Obsessive Compulsive Host/Service Processor Daemon for Nagios
+#
+# processname:	ocpd
+#
+# $Id$
+
+# Source function library
+. /etc/rc.d/init.d/functions
+
+# Get service config - may override defaults
+[ -f /etc/sysconfig/ocpd ] && . /etc/sysconfig/ocpd
+
+# Get network config
+. /etc/sysconfig/network
+
+# Check that networking is up.
+if is_yes "${NETWORKING}"; then
+	if [ ! -f /var/lock/subsys/network -a "$1" != stop -a "$1" != status ]; then
+		msg_network_down "Nagios OCHS Processor Daemon"
+		exit 1
+	fi
+else
+	exit 0
+fi
+
+nagios_cfg=/etc/nagios/nagios.cfg
+nsca=/usr/sbin/send_nsca
+nsca_cfg=/etc/nagios/send_nsca.cfg
+nsca_central_file=/etc/nagios/send_nsca-central
+
+# configtest itself
+# must return non-zero if check failed
+# output is discarded if checkconfig is ran without details
+configtest() {
+	local val ret=0
+
+	# check for nagios setup
+	val=$(awk -F= '/^process_performance_data/{print $2}' $nagios_cfg)
+	if [ "$val" != "1" ]; then
+		echo >&2 "'process_performance_data' must be '1' in $nagios_cfg"
+		ret=1
+	fi
+	val=$(awk -F= '/^host_perfdata_file_mode/{print $2}' $nagios_cfg)
+	if [ "$val" != "p" ]; then
+		echo >&2 "'host_perfdata_file_mode' must be 'p' in $nagios_cfg"
+		ret=1
+	fi
+
+	val=$(awk -F= '/^service_perfdata_file_mode/{print $2}' $nagios_cfg)
+	if [ "$val" != "p" ]; then
+		echo >&2 "'service_perfdata_file_mode' must be 'p' in $nagios_cfg"
+		ret=1
+	fi
+
+	val=$(awk -F= '/^process_performance_data/{print $2}' $nagios_cfg)
+	if [ "$val" != "1" ]; then
+		echo >&2 "'process_performance_data' must be '1' in $nagios_cfg"
+		ret=1
+	fi
+
+	val=$(awk -F= '/^host_perfdata_file_processing_interval/{print $2}' $nagios_cfg)
+	if [ "$val" != "0" ]; then
+		echo >&2 "'host_perfdata_file_processing_interval' must be '0' in $nagios_cfg"
+		ret=1
+	fi
+
+	val=$(awk -F= '/^service_perfdata_file_processing_interval/{print $2}' $nagios_cfg)
+	if [ "$val" != "0" ]; then
+		echo >&2 "'service_perfdata_file_processing_interval' must be '0' in $nagios_cfg"
+		ret=1
+	fi
+
+	# check for nsca
+	val=$(awk '!/#/ { print }' $nsca_central_file)
+	if [ -z "$val" ]; then
+		echo >&2 "central host not set in $nsca_central_file"
+		ret=1
+	fi
+
+	return $ret
+}
+
+# wrapper for configtest
+checkconfig() {
+	local details=${1:-0}
+
+	if [ $details = 1 ]; then
+		# run config test and display report (status action)
+		show "Checking %s configuration" "<service_name>"; busy
+		local out
+		out=`configtest 2>&1`
+		RETVAL=$?
+		if [ $RETVAL = 0 ]; then
+			ok
+		else
+			fail
+		fi
+		[ "$out" ] && echo >&2 "$out"
+	else
+		# run config test and abort with nice message if failed
+		# (for actions checking status before action).
+		configtest >/dev/null 2>&1
+		RETVAL=$?
+		if [ $RETVAL != 0 ]; then
+			show "Checking %s configuration" "<service_name>"; fail
+			nls 'Configuration test failed. See details with %s "checkconfig"' $0
+			exit $RETVAL
+		fi
+	fi
+}
+
+
+start() {
+	# Check if the service is already running?
+	if [ -f /var/lock/subsys/nagios-ocpd ]; then
+		msg_already_running "Nagios OCHS Processor Daemon"
+		return
+	fi
+
+	checkconfig
+	msg_starting "Nagios OCHS Processor Daemon"
+
+	local nsca_host=$(awk '!/#/ { print }' $nsca_central_file)
+	local hostfifo=$(awk -F= '/^host_perfdata_file=/{print $2}' $nagios_cfg)
+	local servicefifo=$(awk -F= '/^service_perfdata_file=/{print $2}' $nagios_cfg)
+
+	# XXX daemon() can't do --user and --fork without start-stop-daemon
+	export RC_LOGGING=no
+	daemon --user nagios --fork /usr/lib/nagios/ocpd -f $hostfifo,$servicefifo -n $nsca -H $nsca_host -c $nsca_cfg -r 1
+
+	RETVAL=$?
+	[ $RETVAL -eq 0 ] && touch /var/lock/subsys/nagios-ocpd
+}
+
+stop() {
+	if [ ! -f /var/lock/subsys/nagios-ocpd ]; then
+		msg_not_running "Nagios OCHS Processor Daemon"
+		return
+	fi
+
+	# Stop daemons.
+	msg_stopping "Nagios OCHS Processor Daemon"
+	killproc OCP_daemon
+	rm -f /var/lock/subsys/nagios-ocpd
+}
+
+condrestart() {
+	if [ ! -f /var/lock/subsys/nagios-ocpd ]; then
+		msg_not_running "Nagios OCHS Processor Daemon"
+		RETVAL=$1
+		return
+	fi
+
+	checkconfig
+	stop
+	start
+}
+
+RETVAL=0
+# See how we were called.
+case "$1" in
+  start)
+  	start
+	;;
+  stop)
+  	stop
+	;;
+  restart)
+	checkconfig
+	stop
+	start
+	;;
+  try-restart)
+	condrestart 0
+	;;
+  force-reload)
+	condrestart 7
+	;;
+  checkconfig|configtest)
+	checkconfig 1
+	;;
+  status)
+	status OCP_daemon
+	RETVAL=$?
+	;;
+  *)
+	msg_usage "$0 {start|stop|restart|try-restart|reload|force-reload|checkconfig|status}"
+	exit 3
+esac
+
+exit $RETVAL

================================================================
Index: packages/nagios-ocpd/ocpd.pl
diff -u /dev/null packages/nagios-ocpd/ocpd.pl:1.1
--- /dev/null	Wed Aug  5 02:30:33 2009
+++ packages/nagios-ocpd/ocpd.pl	Wed Aug  5 02:30:27 2009
@@ -0,0 +1,228 @@
+#!/usr/bin/perl
+# OCP_daemon - Obsessive Compulsive Host/Service Processor daemon for Nagios
+#
+# Copyright (C) 2007 Thomas Guyot-Sionnest <tguyot at gmail.com>
+# Original code Copyright (C) 2006, 2007 Mark Steele
+#       http://www.control-alt-del.org/code
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+#
+use Event::Lib;
+use Getopt::Std;
+use POSIX;
+use strict;
+use warnings;
+use vars qw($PROGNAME $VERSION $READ_SIZE $MAX_LINE_LENGTH $CHILD_TIMEOUT %args);
+
+#####################################################################
+#
+$PROGNAME = 'OCP_daemon';
+$VERSION = '1.0rc4';
+#
+# Try to get that much data each read. Normally a named pipe
+# can't hold more that 4096 bytes.
+$READ_SIZE = 4096;
+#
+# A line longer than this will be discarded.
+$MAX_LINE_LENGTH = 8192;
+#
+# How long to wait for send_nsca. If you're sending huge batch
+# updates on a very slow network you'll likely want to increase this.
+$CHILD_TIMEOUT = 60;
+#
+#####################################################################
+
+# Ignore HUPs in case we've been lazily started from the shell
+$SIG{HUP} = 'IGNORE';
+
+getopts("f:n:H:p:t:c:r:m:h", \%args);
+
+# Print usage if missing options or -h
+if (!$args{'f'} || !$args{'H'} || $args{'h'}) {
+  if (!$args{'h'}) {
+    print "You must specify at least one pipe to read\n" unless ($args{'f'});
+    print "You must specify the host to send data to\n" unless ($args{'H'});
+  }
+  usage();
+}
+
+# Process options
+my @fifos = split (/,/, $args{'f'});
+my $reaper_delay = $args{'r'} || 1;
+my $max_queue = $args{'m'} || 0;
+
+# Construct send_nsca command
+my $nsca = $args{'n'} || '/usr/local/nagios/bin/send_nsca';
+$nsca .= " -H $args{'H'}";
+$nsca .= " -p $args{'p'}" if $args{'p'};
+$nsca .= " -to $args{'t'}" if $args{'t'};
+$nsca .= " -c $args{'c'}" if $args{'c'};
+
+# Sanity checks
+if ($reaper_delay !~ /^\d+$/) {
+  print "reaper_delay must be an integer greater or equal to 0!\n\n";
+  usage();
+}
+
+if ($max_queue !~ /^\d+$/) {
+  print "max_queue must be an integer greater or equal to 0!\n\n";
+  usage();
+}
+
+$max_queue = 0 unless ($reaper_delay);
+
+# send_nsca test run
+system ("$nsca </dev/null >/dev/null 2>/dev/null");
+if ($? != 0) {
+  print "Failed to run '$nsca', bailing out!\n";
+  exit 1;
+}
+
+# Now the fun stuff :)
+
+$0 = $PROGNAME;
+
+# Set up a zombie reaper
+my $signal = signal_new(SIGCHLD, \&reap_chld);
+$signal->add;
+
+my @queue;
+
+## VERY IMPORTANT: You have to open the pipe in O_RDWR, POSIX has rules about 
+##                 using polling calls on pipes, and can't do any on O_RDONLY
+##
+foreach my $fifo (@fifos) {
+  die "$fifo is not a pipe!" unless (-p $fifo);
+  sysopen(my $FIFO, $fifo, O_RDWR | O_NONBLOCK) || die "couldn't open $fifo: $!";
+  my $reader = event_new(\*$FIFO, EV_READ, \&reader);
+  $reader->add;
+}
+
+my $timer;
+if ($reaper_delay) {
+  $timer = timer_new(\&reaper);
+  $timer->add($reaper_delay);
+}
+
+event_mainloop();
+
+sub reap_chld {
+  while (waitpid(-1, WNOHANG) > 0) {
+  }
+}
+
+sub reaper {
+  my $event = shift;
+
+  if (@queue) {
+    my $fork;
+    if (($fork = fork) == 0) {
+      # We're a child, make sure we don't stay around too long...
+      alarm($CHILD_TIMEOUT);
+      $0 = "$0 child";
+
+      open(NSCA, "|$nsca >/dev/null 2>/dev/null") or die "Failed to spawn send_nsca: $!";
+      print NSCA @queue;
+      close(NSCA);
+      exit;
+
+    } elsif (!defined ($fork)) {
+      # Fork failed, no free resources?
+      die "Fork failed, no free resources?"
+    } else {
+      # We're the parent, empty the queue
+      undef @queue;
+    }
+  }
+  # Reschedule ourself if we're using the timer.
+  $event->add($reaper_delay) if ($event);
+}
+
+
+sub reader {
+  my $event = shift;
+  my $fh = $event->fh;
+  my $self = shift;
+  my $data;
+
+  if (scalar($event->args()) > 3) { ## Recursively called ourselves with data passed to function
+    $data = $_[3];
+  }
+
+  my $ret = sysread ($fh, my $buf, $READ_SIZE);
+
+  if (defined ($ret) && $ret == 0) { ## Shouldn't happen
+    #print scalar localtime, " ACK: Got EOF?\n";
+    die;
+  } elsif (!defined ($ret)) { ## Shouldn't happen
+    #print scalar localtime, " ACK: Error condition? $!\n";
+    die;
+  } elsif (!$buf) { ## Shouldn't happen
+    #print scalar localtime, " ACK: Not EOF, not error, but nothing in buffer\n";
+    die;
+  }
+
+  # 
+  # Be safe here...
+  $data .= $buf;
+  while (my $marker = index ($data, "\n") + 1) {
+    push (@queue, substr ($data, 0, $marker));
+    $data = substr ($data, $marker);
+      
+    if ($max_queue && $max_queue <= @queue) {
+      $timer->remove; # Reaper will re-add itself
+      reaper($timer);
+    }
+  }
+
+  # Process queue now if there's no timer
+  reaper(0) unless ($reaper_delay);
+
+  if ($data && length ($data) < $MAX_LINE_LENGTH) {   ## Incomplete line
+    #print "DATA LEFT AFTER PARSING: ------------\n$data\n-------------\n";
+    $event->args($event->fh, EV_READ, $self, $data);
+    $event->add;
+    return;
+  }
+
+  $event->args($event->fh, EV_READ, $self);
+  $event->add;
+}
+
+sub usage {
+  print "$PROGNAME v.$VERSION - Obsessive Compulsive Host/Service Processor daemon\n";
+  print "Usage:\n";
+  print "  $PROGNAME -f <fifo>[,<fifo2>[,<fifoN>...]] -H <nsca_host> [ -n <nsca_bin> ]\n";
+  print "  [ -p <nsca_port> ] [ -t <nsca_timeout> ] [ -c <nsca_config> ]\n";
+  print "  [ -r <reaper_delay> ] [ -m <max_queue> ]\n\n";
+
+  print "Options:\n";
+  print "  -f <fifo>\tComma-separated list of fifo files to read from\n";
+  print "\t\tThese files must be all named pipes (fifo)\n\n";
+
+  print "  -n <nsca_bin>\tsend_nsca command path\n";
+  print "\t\tDefaults to /usr/local/nagios/bin/send_nsca\n\n";
+
+  print "  -H,-p,-t,-c\tSee corresponding send_nsca command\n\n";
+
+  print "  -r <seconds>\tHow long to wait between each nsca flushes\n";
+  print "\t\t0 = as data arrive. Default: 1 second\n";
+  print "\t\tWARNING: Setting this to 0 can be very resource-consuming!\n\n";
+
+  print "  -m <slots>\tMax queue size if reaper_delay is greater than 0\n";
+  print "\t\tA flush will be forced if the queue reach this size\n\n";
+
+  exit 1;
+}
================================================================


More information about the pld-cvs-commit mailing list