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 <[email protected]> +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 <[email protected]> +# 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; +} ================================================================ _______________________________________________ pld-cvs-commit mailing list [email protected] http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit
