Imported Upstream version 0.6.24+dfsg1
This commit is contained in:
52
scripts/Makefile.in
Normal file
52
scripts/Makefile.in
Normal file
@@ -0,0 +1,52 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
LOGDIR=@localstatedir@
|
||||
CFGDIR=@sysconfdir@
|
||||
BINDIR=@bindir@
|
||||
LIBEXECDIR=@libexecdir@
|
||||
CGIDIR=@sbindir@
|
||||
INIT_DIR=@init_dir@
|
||||
INIT_OPTS=-o root -g root
|
||||
HTMLDIR=@datarootdir@
|
||||
INSTALL=@INSTALL@
|
||||
INSTALL_OPTS=@INSTALL_OPTS@
|
||||
PERFDATADIR=@PERFDATA_DIR@
|
||||
|
||||
CP=@CP@
|
||||
|
||||
all html:
|
||||
|
||||
clean:
|
||||
|
||||
distclean: clean
|
||||
-rm -f process_perfdata.pl check_pnp_rrds.pl net2pnp.pl rc.npcd rc.pnp_gearman_worker rrd_convert.pl
|
||||
-rm -f Makefile
|
||||
|
||||
devclean: distclean
|
||||
|
||||
install-init:
|
||||
$(INSTALL) -m 755 $(INIT_OPTS) -d $(DESTDIR)$(INIT_DIR)
|
||||
$(INSTALL) -m 755 $(INIT_OPTS) rc.npcd $(DESTDIR)$(INIT_DIR)/npcd
|
||||
$(INSTALL) -m 755 $(INIT_OPTS) rc.pnp_gearman_worker $(DESTDIR)$(INIT_DIR)/pnp_gearman_worker
|
||||
|
||||
install-processperfdata:
|
||||
$(INSTALL) -m 755 $(INSTALL_OPTS) process_perfdata.pl $(DESTDIR)$(LIBEXECDIR)
|
||||
|
||||
install-plugins:
|
||||
$(INSTALL) -m 755 $(INSTALL_OPTS) check_pnp_rrds.pl $(DESTDIR)$(LIBEXECDIR)
|
||||
|
||||
install-rrdconvert:
|
||||
$(INSTALL) -m 755 $(INSTALL_OPTS) rrd_convert.pl $(DESTDIR)$(LIBEXECDIR)
|
||||
|
||||
install-rrdmodify:
|
||||
$(INSTALL) -m 755 $(INSTALL_OPTS) rrd_modify.pl $(DESTDIR)$(LIBEXECDIR)
|
||||
|
||||
install:
|
||||
$(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(PERFDATADIR)
|
||||
$(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBEXECDIR)
|
||||
$(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LOGDIR)/stats
|
||||
$(MAKE) install-processperfdata
|
||||
$(MAKE) install-plugins
|
||||
$(MAKE) install-rrdconvert
|
||||
$(MAKE) install-rrdmodify
|
||||
|
||||
298
scripts/check_pnp_rrds.pl.in
Normal file
298
scripts/check_pnp_rrds.pl.in
Normal file
@@ -0,0 +1,298 @@
|
||||
#!@PERL@
|
||||
# nagios: -epn
|
||||
## check_pnp_rrds - PNP4Nagios.
|
||||
## Copyright (c) 2006-2009 Joerg Linge (http://www.pnp4nagios.org)
|
||||
##
|
||||
## 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
use File::Find;
|
||||
use File::Basename;
|
||||
use warnings;
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
|
||||
my $read_input;
|
||||
if (eval {require "Term/ReadKey.pm"}) {
|
||||
import Term::ReadKey;
|
||||
$read_input = \&read_key;
|
||||
} else {
|
||||
$read_input = \&read_stdin;
|
||||
}
|
||||
|
||||
Getopt::Long::Configure('bundling');
|
||||
my ( $opt_V, $opt_h, $opt_b );
|
||||
my $opt_a = 7;
|
||||
my $opt_dxml = 0;
|
||||
my $opt_drrd = 0;
|
||||
my $opt_w = 1;
|
||||
my $opt_c = 10;
|
||||
my $opt_t = 10;
|
||||
my $opt_p = "@PERFDATA_DIR@";
|
||||
my $opt_ncmd = "/usr/local/nagios/var/rw/nagios.cmd";
|
||||
my $opt_phost = "";
|
||||
my $opt_pservice = "";
|
||||
my $opt_ignore;
|
||||
my $VERSION = "@PKG_VERSION@";
|
||||
my $PROGNAME = basename($0);
|
||||
my $PASV = 0;
|
||||
my $USER = getpwuid($<);
|
||||
|
||||
sub print_help () ;
|
||||
sub print_usage () ;
|
||||
|
||||
GetOptions(
|
||||
"V" => \$opt_V,
|
||||
"version" => \$opt_V,
|
||||
"h" => \$opt_h,
|
||||
"help" => \$opt_h,
|
||||
"t=i" => \$opt_t,
|
||||
"timeout=i" => \$opt_t,
|
||||
"w=i" => \$opt_w,
|
||||
"warning=i" => \$opt_w,
|
||||
"c=i" => \$opt_c,
|
||||
"critical=i" => \$opt_c,
|
||||
"fileage=i" => \$opt_a,
|
||||
"a=i" => \$opt_a,
|
||||
"deletexml" => \$opt_dxml,
|
||||
"deleterrd" => \$opt_drrd,
|
||||
"p=s" => \$opt_p,
|
||||
"rrdpath=s" => \$opt_p,
|
||||
"passiv-hostname=s" => \$opt_phost,
|
||||
"passiv-servicedesc=s" => \$opt_pservice,
|
||||
"nagios-cmd=s" => \$opt_ncmd,
|
||||
"ignore-hosts=s" => \$opt_ignore,
|
||||
) or print_help();
|
||||
|
||||
|
||||
|
||||
print_help() if ($opt_h);
|
||||
|
||||
my $RRD_ERRORS = 0;
|
||||
my $RRD_ERR = "";
|
||||
my $RRD_AGE = "";
|
||||
my $XML_COUNT_AGE = 0;
|
||||
my $XML_COUNT = 0;
|
||||
my $RRD_COUNT = 0;
|
||||
my $RC = 0;
|
||||
my $OUT = "OK: ";
|
||||
my $PERF = "";
|
||||
|
||||
$SIG{'ALRM'} = sub {
|
||||
print "UNKNOWN: Timeout after $opt_t sec.\n";
|
||||
exit 3;
|
||||
};
|
||||
|
||||
alarm($opt_t);
|
||||
|
||||
$PASV = 1 if($opt_phost && $opt_pservice && $opt_ncmd);
|
||||
|
||||
if($PASV == 1 && !-e $opt_ncmd){
|
||||
print "\n\nUNKNOWN: $opt_ncmd does not exist\n\n";
|
||||
print_usage();
|
||||
exit 3;
|
||||
}
|
||||
|
||||
if($PASV == 1 && !-w $opt_ncmd){
|
||||
print "\n\nUNKNOWN: $opt_ncmd is not writable by \"$USER\" \n\n";
|
||||
print_usage();
|
||||
exit 3;
|
||||
}
|
||||
|
||||
if ( -r $opt_p ) {
|
||||
find { no_chdir => 1,
|
||||
wanted => \&inspect_files,
|
||||
} => $opt_p
|
||||
}
|
||||
else {
|
||||
print "UNKNOWN: $opt_p not readable\n";
|
||||
exit 3;
|
||||
}
|
||||
|
||||
sub inspect_files {
|
||||
my $file = $File::Find::name;
|
||||
return unless m/\.xml$/;
|
||||
return unless -f $file;
|
||||
my $found = -1;
|
||||
my $TXT = "invalid xml file";
|
||||
my $host;
|
||||
my $service;
|
||||
my $dir = $File::Find::dir;
|
||||
if ( $file =~ /\.xml/ ) {
|
||||
$service = basename($file);
|
||||
$host = dirname($file);
|
||||
$host = basename($host);
|
||||
|
||||
if ( defined $opt_ignore && $host =~ $opt_ignore ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$XML_COUNT++;
|
||||
open F, $file or print "couldn't open $file\n" && return;
|
||||
while (<F>) {
|
||||
if (m/<RC>(.*)<\/RC>/) {
|
||||
$found = $1;
|
||||
}
|
||||
if ( $found != 0 && m/<TXT>(.*)<\/TXT>/ ) {
|
||||
$TXT = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close F;
|
||||
my $mtime = ( stat($file) )[9];
|
||||
my $fileage = ( ( time() - $mtime ) / 86400 );
|
||||
if ( $fileage >= ( $opt_a ) ) {
|
||||
if ($opt_dxml) {
|
||||
print $host . " / " . $service . " is ".$fileage." days old. Delete? (y/n/q) ";
|
||||
my $ret1 = &$read_input;
|
||||
# my $ret1 = <>;
|
||||
if ($ret1 =~ /y/i) {
|
||||
if (! unlink($file)) {
|
||||
print " ...Deletion of $file failed!";
|
||||
} else {
|
||||
print " ...Deleted file $file.";
|
||||
}
|
||||
} elsif ($ret1 =~ /q/i) {
|
||||
exit;
|
||||
}
|
||||
print "\n";
|
||||
|
||||
if ($opt_drrd) {
|
||||
my $rrd = $file;
|
||||
$rrd =~ s/\.[^.]+$//;
|
||||
$rrd .= ".rrd";
|
||||
if (-e $rrd) {
|
||||
print " Delete " . basename($rrd) . "? (y/n/q) ";
|
||||
my $ret2 = &$read_input;
|
||||
if ($ret2 =~ /y/i) {
|
||||
unlink($rrd) ? print " $rrd deleted." : print " Deletion of $rrd failed.";
|
||||
} elsif ($ret2 =~/q/i) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
print "\n\n";
|
||||
} else {
|
||||
$XML_COUNT_AGE++;
|
||||
$RRD_AGE .= sprintf(".../%s/%s is %d days old.\n",$host,$service,$fileage);
|
||||
}
|
||||
}
|
||||
$RRD_ERRORS++ if $found != "0";
|
||||
$RRD_ERR .= ".../$host/$service $TXT\n" if $found != 0;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sub PROCESS_SERVICE_CHECK_RESULT {
|
||||
my $RC = shift;
|
||||
my $OUT = shift;
|
||||
my $time = time();
|
||||
my $CommandLine = "[$time] PROCESS_SERVICE_CHECK_RESULT;$opt_phost;$opt_pservice;$RC;$OUT";
|
||||
|
||||
print "PROCESS_SERVICE_CHECK_RESULT\n";
|
||||
print $OUT;
|
||||
|
||||
open(CommandFile, ">>$opt_ncmd");
|
||||
print CommandFile $CommandLine;
|
||||
close CommandFile;
|
||||
}
|
||||
|
||||
|
||||
if ( $XML_COUNT == 0 ) {
|
||||
print "UNKNOWN: No XML files found in $opt_p\n";
|
||||
exit 3;
|
||||
}
|
||||
|
||||
if ( $RRD_ERRORS >= $opt_w || $XML_COUNT_AGE >= $opt_w ) {
|
||||
$RC = 1;
|
||||
$OUT = "WARNING: ";
|
||||
}
|
||||
if ( $RRD_ERRORS >= $opt_c || $XML_COUNT_AGE >= $opt_c ) {
|
||||
$RC = 2;
|
||||
$OUT = "CRITICAL: ";
|
||||
}
|
||||
|
||||
$OUT .= "$XML_COUNT XML Files checked. $RRD_ERRORS RRD Errors found. $XML_COUNT_AGE old XML Files found";
|
||||
$PERF = " | total=$XML_COUNT errors=$RRD_ERRORS;$opt_w;$opt_c;0;$XML_COUNT old=$XML_COUNT_AGE;$opt_w;$opt_c;0;$XML_COUNT\n";
|
||||
$OUT .= $PERF . $RRD_ERR . $RRD_AGE;
|
||||
if($PASV == 0){
|
||||
print $OUT;
|
||||
exit $RC;
|
||||
}else{
|
||||
PROCESS_SERVICE_CHECK_RESULT($RC,$OUT);
|
||||
}
|
||||
|
||||
sub print_help (){
|
||||
print "Copyright (c) 2008 Joerg Linge, Pitchfork\@pnp4nagios.org\n\n";
|
||||
print "\n";
|
||||
print "$PROGNAME $VERSION\n";
|
||||
print "$PROGNAME is used to find old or unusable RRD Files\n";
|
||||
print "\n";
|
||||
print_usage();
|
||||
print "\n";
|
||||
print "\n";
|
||||
print_support();
|
||||
exit 3;
|
||||
}
|
||||
|
||||
sub print_usage () {
|
||||
print "USAGE: $PROGNAME [OPTIONS]\n";
|
||||
print " -w,--warning\n";
|
||||
print " Default: $opt_w\n";
|
||||
print " -c,--critical\n";
|
||||
print " Default: $opt_c\n";
|
||||
print " -a,--fileage Max XML File Age.\n";
|
||||
print " Default: $opt_a Days\n";
|
||||
print " -p,--rrdpath Path to your RRD and XML Files.\n";
|
||||
print " Default: $opt_p\n";
|
||||
print " -t,--timeout Max Plugin Runtime.\n";
|
||||
print " Default: $opt_t Seconds\n";
|
||||
print " --ignore-hosts \n";
|
||||
print " Regular expression to ignore a set of hosts";
|
||||
print "\n\n";
|
||||
print " --deletexml\n";
|
||||
print " delete old XML files (interactive). \n";
|
||||
print " --deleterrd\n";
|
||||
print " delete old RRD files (interactive, only if --deletexml). \n";
|
||||
print "\n\n";
|
||||
print " --passiv-hostname=\n";
|
||||
print " Nagios Hostname\n";
|
||||
print " --passiv-servicedesc=\n";
|
||||
print " Nagios Servicedesc\n";
|
||||
print " --nagios-cmd=\n";
|
||||
print " External Command File (nagios.cmd)\n";
|
||||
|
||||
}
|
||||
|
||||
sub print_support {
|
||||
print "SUPPORT: http://www.pnp4nagios.org/pnp/\n";
|
||||
print "\n\n";
|
||||
}
|
||||
|
||||
sub read_stdin {
|
||||
my $rk;
|
||||
$rk = <>;
|
||||
return $rk;
|
||||
}
|
||||
|
||||
sub read_key {
|
||||
my $rk;
|
||||
ReadMode('cbreak');
|
||||
$rk = ReadKey(0);
|
||||
ReadMode('normal');
|
||||
return $rk;
|
||||
}
|
||||
# vim: set ai tabstop=4 shiftwidth=4
|
||||
1596
scripts/process_perfdata.pl.in
Normal file
1596
scripts/process_perfdata.pl.in
Normal file
File diff suppressed because it is too large
Load Diff
162
scripts/rc.npcd.in
Normal file
162
scripts/rc.npcd.in
Normal file
@@ -0,0 +1,162 @@
|
||||
#!@SHELL@
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
# Provides: npcd
|
||||
# Required-Start:
|
||||
# Required-Stop:
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: @PKG_NAME@ NPCD Daemon Version @PKG_VERSION@
|
||||
# Description: Nagios Performance Data C Daemon
|
||||
### END INIT INFO
|
||||
|
||||
# chkconfig: 345 99 01
|
||||
#
|
||||
# File : npcd
|
||||
#
|
||||
|
||||
servicename=@npcd_name@
|
||||
prefix=@prefix@
|
||||
exec_prefix=${prefix}
|
||||
NpcdBin=@bindir@/@npcd_name@
|
||||
NpcdCfgFile=@sysconfdir@/npcd.cfg
|
||||
NpcdVarDir=@localstatedir@
|
||||
NpcdRunFile=/var/run/npcd.pid
|
||||
NpcdLockDir=/var/lock/subsys
|
||||
NpcdLockFile=@npcd_name@
|
||||
NpcdUser=@nagios_user@
|
||||
NpcdGroup=@nagios_grp@
|
||||
|
||||
status_npcd (){
|
||||
pid_npcd
|
||||
if ps -p $NpcdPID > /dev/null 2>&1; then
|
||||
return 0
|
||||
else
|
||||
if test -f $NpcdLockDir/$NpcdLockFile; then
|
||||
return 2
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
printstatus_npcd(){
|
||||
if status_npcd $1 $2; then
|
||||
echo "$servicename (pid $NpcdPID) is running..."
|
||||
exit 0
|
||||
elif test $? -eq 2; then
|
||||
echo "$servicename is not running but subsystem locked"
|
||||
exit 2
|
||||
else
|
||||
echo "$servicename is not running"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
killproc_npcd (){
|
||||
kill $2 $NpcdPID
|
||||
}
|
||||
|
||||
pid_npcd (){
|
||||
if test ! -f $NpcdRunFile; then
|
||||
return 1
|
||||
fi
|
||||
NpcdPID=`head -n 1 $NpcdRunFile`
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
# Source function library
|
||||
# Solaris doesn't have an rc.d directory, so do a test first
|
||||
if [ -f /etc/rc.d/init.d/functions ]; then
|
||||
. /etc/rc.d/init.d/functions
|
||||
elif [ -f /etc/init.d/functions ]; then
|
||||
. /etc/init.d/functions
|
||||
fi
|
||||
|
||||
# Check that npcd exists.
|
||||
if [ ! -f $NpcdBin ]; then
|
||||
echo "Executable file $NpcdBin not found. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check that npcd.cfg exists.
|
||||
if [ ! -f $NpcdCfgFile ]; then
|
||||
echo "Configuration file $NpcdCfgFile not found. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
|
||||
start)
|
||||
status_npcd
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "$servicename already started..."
|
||||
exit 1
|
||||
fi
|
||||
echo -n "Starting $servicename:"
|
||||
touch $NpcdRunFile
|
||||
chown $NpcdUser:$NpcdGroup $NpcdRunFile
|
||||
$NpcdBin -d -f $NpcdCfgFile
|
||||
if [ -d $NpcdLockDir ]; then touch $NpcdLockDir/$NpcdLockFile; fi
|
||||
echo " done."
|
||||
exit 0
|
||||
;;
|
||||
|
||||
stop)
|
||||
status_npcd
|
||||
if ! [ $? -eq 0 ]; then
|
||||
echo "$servicename was not running... could not stop"
|
||||
exit 1
|
||||
fi
|
||||
echo -n "Stopping $servicename: "
|
||||
|
||||
pid_npcd
|
||||
killproc_npcd npcd
|
||||
|
||||
# now we have to wait for npcd to exit and remove its
|
||||
# own NpcdRunFile, otherwise a following "start" could
|
||||
# happen, and then the exiting npcd will remove the
|
||||
# new NpcdRunFile, allowing multiple npcd daemons
|
||||
# to (sooner or later) run - John Sellens
|
||||
#echo -n 'Waiting for npcd to exit .'
|
||||
for i in 1 2 3 4 5 6 7 8 9 10 ; do
|
||||
if status_npcd > /dev/null; then
|
||||
echo -n '.'
|
||||
sleep 1
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
if status_npcd > /dev/null; then
|
||||
echo ''
|
||||
echo 'Warning - $servicename did not exit in a timely manner'
|
||||
else
|
||||
echo 'done.'
|
||||
fi
|
||||
rm -f $NpcdLockDir/$NpcdLockFile
|
||||
;;
|
||||
|
||||
status)
|
||||
printstatus_npcd
|
||||
;;
|
||||
|
||||
reload)
|
||||
$0 restart
|
||||
;;
|
||||
|
||||
restart)
|
||||
$0 stop
|
||||
$0 start
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: $servicename {start|stop|restart|status}"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# End of this script
|
||||
113
scripts/rc.pnp_gearman_worker.in
Normal file
113
scripts/rc.pnp_gearman_worker.in
Normal file
@@ -0,0 +1,113 @@
|
||||
#!@SHELL@
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: pnp_gearman_worker
|
||||
# Required-Start: $all
|
||||
# Required-Stop: $all
|
||||
# Should-Start:
|
||||
# Should-Stop:
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Start/Stop the pnp4nagios gearman worker
|
||||
### END INIT INFO
|
||||
|
||||
DAEMON="@libexecdir@/process_perfdata.pl"
|
||||
CFG="@sysconfdir@/process_perfdata.cfg"
|
||||
NAME=pnp_gearman_worker
|
||||
PIDFILE=@localstatedir@/${NAME}.pid
|
||||
LOCKFILE=/var/lock/subsys/${NAME}
|
||||
USER=@nagios_user@
|
||||
USERID=`id -u`
|
||||
CMD="$DAEMON --pidfile=$PIDFILE --config=$CFG --gearman --daemon"
|
||||
|
||||
function get_status() {
|
||||
pid=`cat $PIDFILE 2>/dev/null`
|
||||
if [ "$pid" != "" ]; then
|
||||
ps -p $pid > /dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "$NAME is running with pid $pid"
|
||||
return 0;
|
||||
fi
|
||||
fi
|
||||
echo "$NAME is not running"
|
||||
return 1;
|
||||
}
|
||||
|
||||
function kill_procs() {
|
||||
pid=`cat $PIDFILE 2>/dev/null`
|
||||
if [ -z $pid ]; then
|
||||
echo ". Not running."
|
||||
else
|
||||
# do a kill if still now down
|
||||
ps -p $pid > /dev/null 2>&1 && kill $pid
|
||||
for x in 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5; do
|
||||
echo -n "."
|
||||
ps -p $pid > /dev/null 2>&1 && sleep 1;
|
||||
done
|
||||
ps -p $pid > /dev/null 2>&1;
|
||||
if [ $? -ne 0 ]; then
|
||||
rm -f $PIDFILE
|
||||
if [ "$USERID" -eq 0 ]; then
|
||||
rm -f $LOCKFILE
|
||||
fi
|
||||
echo "done"
|
||||
exit 0;
|
||||
else
|
||||
echo "failed"
|
||||
exit 1;
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Starting $NAME "
|
||||
get_status > /dev/null;
|
||||
if [ $? = 0 ]; then
|
||||
echo "failed"
|
||||
echo "$NAME already running"
|
||||
exit 0;
|
||||
fi
|
||||
|
||||
if [ "$USERID" -eq 0 ]; then
|
||||
su -s $SHELL - $USER -c "$CMD"
|
||||
else
|
||||
$CMD
|
||||
fi
|
||||
if [ $? -eq 0 ]; then
|
||||
if [ "$USERID" -eq 0 ]; then
|
||||
touch $LOCKFILE
|
||||
fi
|
||||
echo "done"
|
||||
exit 0;
|
||||
else
|
||||
echo "failed"
|
||||
exit 1;
|
||||
fi
|
||||
;;
|
||||
stop)
|
||||
echo -n "Stopping $NAME"
|
||||
pid=`cat $PIDFILE 2>/dev/null`
|
||||
if [ -z $pid ]; then
|
||||
echo ". Not running."
|
||||
else
|
||||
# kill if still running
|
||||
ps -p $pid > /dev/null 2>&1 && kill_procs;
|
||||
fi
|
||||
;;
|
||||
status)
|
||||
get_status;
|
||||
exit $?;
|
||||
;;
|
||||
restart)
|
||||
$0 stop && sleep 1 && $0 start
|
||||
exit $?
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $NAME {start|stop|status|restart}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
555
scripts/rrd_convert.pl.in
Normal file
555
scripts/rrd_convert.pl.in
Normal file
@@ -0,0 +1,555 @@
|
||||
#!@PERL@
|
||||
## @PKG_NAME@–@PKG_VERSION@ rrd_convert.pl
|
||||
## Copyright (c) 2006-2010 Joerg Linge (http://www.pnp4nagios.org)
|
||||
##
|
||||
## 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
@PERL_LIB_PATH_CODE@
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
use Time::HiRes qw(gettimeofday tv_interval);
|
||||
use File::Find;
|
||||
use File::Copy;
|
||||
|
||||
if( $< == 0 ){
|
||||
print "dont try this as root \n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
#
|
||||
# Some global Vars
|
||||
#
|
||||
|
||||
my %conf = (
|
||||
CFG_DIR => "@sysconfdir@/",
|
||||
RRDPATH => "@PERFDATA_DIR@",
|
||||
RRDTOOL => "@RRDTOOL@",
|
||||
LOG_LEVEL => 0,
|
||||
DRY_RUN => 0,
|
||||
FORCE => 0,
|
||||
RRD_BACKUP => 1,
|
||||
RRD_STORAGE_TYPE => "SINGLE",
|
||||
TMP_DIR => '/tmp/rrd_convert',
|
||||
RRD_DAEMON_OPTS => "",
|
||||
XML_MAX_AGE => 3600,
|
||||
);
|
||||
|
||||
Getopt::Long::Configure('bundling');
|
||||
my ( $opt_V, $opt_h, $opt_c, $opt_l, $opt_x, $opt_p );
|
||||
# defaults
|
||||
$opt_x = 1;
|
||||
|
||||
GetOptions(
|
||||
"V|version" => \$opt_V,
|
||||
"h|help" => \$opt_h,
|
||||
"c|check_command=s" => \$opt_c,
|
||||
"p|cfg_dir=s" => \$opt_p,
|
||||
"l|list_commands" => \$opt_l,
|
||||
"x|no_structure_check" => \$opt_x,
|
||||
"d|dry-run" => \$conf{DRY_RUN},
|
||||
"t|tmp_dir=s" => \$conf{TMP_DIR},
|
||||
"force" => \$conf{FORCE},
|
||||
);
|
||||
|
||||
print_help() if $opt_h;
|
||||
print_help_opt_p() if !$opt_p;
|
||||
print_help() if !$opt_c and !$opt_l;
|
||||
print_version() if $opt_V;
|
||||
|
||||
if($opt_p){
|
||||
$conf{CFG_DIR} = $opt_p;
|
||||
}
|
||||
parse_config($conf{CFG_DIR}."/process_perfdata.cfg");
|
||||
if ( $conf{RRD_DAEMON_OPTS} ){
|
||||
$conf{RRD_DAEMON_OPTS} = "--daemon=".$conf{RRD_DAEMON_OPTS};
|
||||
}
|
||||
|
||||
my @STRUCT;
|
||||
my %FILEHANDLE;
|
||||
|
||||
my @commands; # list of commands
|
||||
my @worklist; # list of found xml files
|
||||
|
||||
my %ds_list;
|
||||
my %original_ds_list;
|
||||
my $max_age = time() - $conf{XML_MAX_AGE};
|
||||
|
||||
my %stats = (
|
||||
'rrd_in' => 0,
|
||||
'rrd_out' => 0,
|
||||
'old_xml' => 0,
|
||||
'xml_without_rrd' => 0,
|
||||
'runtime' => 0,
|
||||
);
|
||||
|
||||
main();
|
||||
|
||||
sub main{
|
||||
check_storage_type();
|
||||
find(\&wanted_xml_files, $conf{RRDPATH});
|
||||
summary();
|
||||
if($opt_l){ # List commands and exit
|
||||
summary_command_list();
|
||||
exit;
|
||||
}
|
||||
if($#worklist+1 > 0 ){
|
||||
my $answer = read_choice("Start Converter [n|y]?");
|
||||
unless ( $answer =~ m/^y$/i ){
|
||||
print "Exit...\n";
|
||||
exit;
|
||||
}
|
||||
}else{
|
||||
print "Check Command '".$opt_c."' not found in any XML File\n";
|
||||
print "\n";
|
||||
print "\n";
|
||||
summary_command_list();
|
||||
exit;
|
||||
}
|
||||
check_custom_template();
|
||||
write_custom_template();
|
||||
my $t0 = [gettimeofday];
|
||||
my $i = 0;
|
||||
foreach my $xmlfile ( @worklist ) {
|
||||
$i++;
|
||||
undef %ds_list;
|
||||
undef %original_ds_list;
|
||||
my($host,$service) = parse_xml_filename($xmlfile);
|
||||
my ($rrdfile) = $xmlfile =~ /^(.*)\.xml$/;
|
||||
$rrdfile .= ".rrd";
|
||||
if(-r $rrdfile){
|
||||
create_dir($conf{TMP_DIR});
|
||||
my $dumpfile = sprintf("%s/%s-%s.dump",$conf{TMP_DIR},$host,$service);
|
||||
print "File ".$i."/".($#worklist+1)."\n";
|
||||
rrdtool_dump($rrdfile,$dumpfile);
|
||||
parse_pnp_xml($xmlfile);
|
||||
build_ds_list($rrdfile);
|
||||
next if check_ds_list();
|
||||
open_files($host,$service);
|
||||
manipulate_rrd_dump($dumpfile);
|
||||
close_files();
|
||||
restore_files($host,$service);
|
||||
backup_rrd_file($rrdfile);
|
||||
}
|
||||
}
|
||||
my $t1 = [gettimeofday];
|
||||
$stats{runtime} = tv_interval $t0, $t1;
|
||||
print "DONE\n";
|
||||
stats();
|
||||
}
|
||||
|
||||
|
||||
sub build_ds_list{
|
||||
my $rrdfile = shift;
|
||||
my @info;
|
||||
@info = `$conf{'RRDTOOL'} info $rrdfile`;
|
||||
if( $? > 0 ){
|
||||
print "ERROR: $conf{'RRDTOOL'} info $rrdfile returns with $?\n";
|
||||
exit 1;
|
||||
}
|
||||
foreach(@info){
|
||||
if(m/ds\[(\d+)\]\.type/ ) {
|
||||
$ds_list{$1} = $1;
|
||||
}
|
||||
}
|
||||
my $test = keys %ds_list;
|
||||
%original_ds_list = %ds_list;
|
||||
}
|
||||
|
||||
sub check_ds_list{
|
||||
my $rrd_ds_count = keys %ds_list;
|
||||
my $xml_ds_count = $#STRUCT;
|
||||
if($rrd_ds_count == $xml_ds_count){
|
||||
return 0;
|
||||
}elsif($rrd_ds_count <= $xml_ds_count && $opt_x){
|
||||
printf("OK: RRD contains '%s' DS but XML contains '%s'. Convert forced by --no_structure_check\n",$rrd_ds_count,$xml_ds_count);
|
||||
return 0;
|
||||
}else{
|
||||
printf ("ERROR: RRD Structure mismatch. DS Count is '%s' but should be '%s'\n",$rrd_ds_count,$xml_ds_count);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
sub wanted_xml_files{
|
||||
if(m/.xml$/){
|
||||
#printf("File: %s\n",$File::Find::name);
|
||||
my $xmlfile = $File::Find::name;
|
||||
my ($rrdfile) = $xmlfile =~ /^(.*)\.xml$/;
|
||||
$rrdfile .= ".rrd";
|
||||
my $mtime = (stat($xmlfile))[9];
|
||||
if ( $mtime < $max_age ){
|
||||
$stats{old_xml}++;
|
||||
return;
|
||||
}
|
||||
open(XML, $xmlfile);
|
||||
while (<XML>) {
|
||||
if(/TEMPLATE>(.*)</){
|
||||
my ($t) = split("!",$1);
|
||||
push(@commands,$t);
|
||||
if(( defined $opt_c) and ($t =~ /^$opt_c$/)){
|
||||
if( -e $rrdfile ){
|
||||
#print "Found: ".$t." in ".$xmlfile."\n";
|
||||
push(@worklist,$xmlfile);
|
||||
}else{
|
||||
$stats{xml_without_rrd}++;
|
||||
}
|
||||
}elsif(( defined $opt_c) and ($opt_c eq 'ALL')){
|
||||
if( -e $rrdfile ){
|
||||
# Keyword 'ALL' retunrs all XML Files
|
||||
push(@worklist,$xmlfile);
|
||||
}else{
|
||||
$stats{xml_without_rrd}++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
close(XML);
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_xml_filename{
|
||||
my $xmlfile = shift;
|
||||
$_ = $xmlfile;
|
||||
if( m/([^\/]+)\/([^\/]+)\.xml$/i ){
|
||||
return ($1, $2);
|
||||
}
|
||||
}
|
||||
sub summary{
|
||||
my %seen;
|
||||
my @uniqed = grep !$seen{$_}++, @commands;
|
||||
print "\n";
|
||||
printf "%-40s %s\n" ,"Search pattern",$opt_c if( defined ($opt_c) );
|
||||
printf "%-40s %s\n" ,"XML Files analyzed",$#commands+1;
|
||||
printf "%-40s %s\n" ,"XML Files found",$#worklist+1;
|
||||
printf "%-40s %s\n" ,"XML Files without RRD",$stats{'xml_without_rrd'};
|
||||
printf "%-40s %s\n" ,"Old XML Files ignored",$stats{'old_xml'};
|
||||
printf "%-40s %s\n" ,"Number of unique check_commands",$#uniqed+1;
|
||||
if($conf{DRY_RUN} == 1){
|
||||
printf "%-40s %s\n" ,"Dry run?","[YES]";
|
||||
printf "%-40s %s\n" ,"Temp Directory",$conf{TMP_DIR};
|
||||
print "\n\n";
|
||||
print "This is only a 'dry run'. The new RRD Files are stored in '$conf{TMP_DIR}'\n";
|
||||
print "\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub summary_command_list{
|
||||
my %seen;
|
||||
my @uniqed = grep !$seen{$_}++, @commands;
|
||||
printf "\\ List of Check Commands\n";
|
||||
foreach my $key (sort { $seen{$b} <=> $seen{$a} } keys %seen ) {
|
||||
printf " |- %-36s %5s\n",$key,$seen{$key};
|
||||
}
|
||||
}
|
||||
|
||||
sub stats{
|
||||
print "\n\n \\Statistics:\n";
|
||||
foreach my $key (sort { $stats{$b} cmp $stats{$a} } keys %stats ) {
|
||||
printf " |- %-15s %s\n",$key,$stats{$key};
|
||||
}
|
||||
}
|
||||
|
||||
sub create_dir{
|
||||
my $dir = shift;
|
||||
unless ( -d "$dir" ) {
|
||||
unless ( mkdir "$dir" ) {
|
||||
print "ERROR: $dir is not writable\n";
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub open_files(){
|
||||
my $host = shift;
|
||||
my $service = shift;
|
||||
foreach my $ds (keys %ds_list){
|
||||
my $file = sprintf("%s/%s-%s-%s.restore",$conf{TMP_DIR},$host,$service,$STRUCT[$ds]{NAME});
|
||||
#print "Open Filehandle ".$file."\n";
|
||||
open($FILEHANDLE{$ds}, ">", $file);
|
||||
}
|
||||
}
|
||||
|
||||
sub close_files(){
|
||||
foreach my $ds (keys %ds_list){
|
||||
#$ds--;
|
||||
#print "Close Filehandle ".$STRUCT[$ds]{NAME}."\n";
|
||||
close($FILEHANDLE{$ds});
|
||||
}
|
||||
}
|
||||
|
||||
sub write_to_files{
|
||||
my $data = shift;
|
||||
foreach my $ds (keys %ds_list){
|
||||
print { $FILEHANDLE{$ds} } $data;
|
||||
}
|
||||
}
|
||||
|
||||
sub restore_files(){
|
||||
my $host = shift;
|
||||
my $service = shift;
|
||||
my $err;
|
||||
$| = 1;
|
||||
print "Restoring File\n";
|
||||
foreach my $ds (keys %ds_list){
|
||||
my $rrdfile = '';
|
||||
my $restorefile = sprintf("%s/%s-%s-%s.restore",$conf{TMP_DIR},$host,$service,$STRUCT[$ds]{NAME});
|
||||
if( $conf{'DRY_RUN'} == 1 ){
|
||||
$rrdfile = sprintf("%s/%s/%s_%s.rrd",$conf{TMP_DIR},$host,$service,$STRUCT[$ds]{NAME});
|
||||
create_dir(sprintf("%s/%s", $conf{TMP_DIR},$host ));
|
||||
}else{
|
||||
$rrdfile = sprintf("%s/%s/%s_%s.rrd",$conf{RRDPATH},$host,$service,$STRUCT[$ds]{NAME});
|
||||
}
|
||||
print "$rrdfile\n";
|
||||
$err = system("$conf{'RRDTOOL'} restore -f '$restorefile' '$rrdfile'");
|
||||
if($err){
|
||||
printf("RRDtool Error: %s\n",$err);
|
||||
exit;
|
||||
}
|
||||
unlink($restorefile);
|
||||
$stats{rrd_out}++;
|
||||
}
|
||||
print "... done\n";
|
||||
$| = 0;
|
||||
}
|
||||
|
||||
sub backup_rrd_file{
|
||||
my $rrdfile = shift;
|
||||
if ( $conf{RRD_BACKUP} == 1 ){
|
||||
move($rrdfile, $rrdfile.".backup");
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_pnp_xml{
|
||||
my $xmlfile = shift;
|
||||
undef @STRUCT;
|
||||
#print "reading $xmlfile\n";
|
||||
open(XML, $xmlfile);
|
||||
my $DATASOURCE = 0;
|
||||
while (<XML>) {
|
||||
if(/<DATASOURCE>/){
|
||||
$DATASOURCE++;
|
||||
}
|
||||
if(/<RRD>/){
|
||||
$DATASOURCE = 0;
|
||||
}
|
||||
if(/<([A-Z_]+)>(.*)<\/[A-Z_]+>/ && $DATASOURCE != -1){
|
||||
$STRUCT[$DATASOURCE]{$1} = $2;
|
||||
}
|
||||
}
|
||||
close(XML);
|
||||
return @STRUCT;
|
||||
}
|
||||
|
||||
sub rrdtool_dump{
|
||||
my $rrdfile = shift;
|
||||
my $dumpfile = shift;
|
||||
my $err;
|
||||
print "RRDtool dump to $dumpfile\n";
|
||||
if ( $conf{RRD_DAEMON_OPTS} ){
|
||||
$err = system("$conf{'RRDTOOL'} dump $conf{RRD_DAEMON_OPTS} $rrdfile > $dumpfile");
|
||||
}else{
|
||||
$err = system("$conf{'RRDTOOL'} dump $rrdfile > $dumpfile");
|
||||
}
|
||||
if($err){
|
||||
printf("RRDtool Error: %s\n",$err);
|
||||
exit;
|
||||
}
|
||||
$stats{rrd_in}++;
|
||||
return $dumpfile;
|
||||
}
|
||||
|
||||
sub manipulate_rrd_dump{
|
||||
my $tmpfile = shift;
|
||||
my $i = 0;
|
||||
open (XML,$tmpfile);
|
||||
my @ROW = ();
|
||||
my $tmpds = 1;
|
||||
my $inside_ds_block = 0;
|
||||
print "Manipulating $tmpfile\n";
|
||||
while (<XML>){
|
||||
$i++;
|
||||
unless ( $i % 5000 ){
|
||||
$| = 1; print "."; $| = 0;
|
||||
}
|
||||
my $d = $_;
|
||||
#
|
||||
# A Data Row
|
||||
if(m/<row>/){
|
||||
m/(.*<row>)/;
|
||||
my $rowstart = $1;
|
||||
@ROW = m{<v>([^<].*?)<\/v>}gc;
|
||||
my $fh = 1;
|
||||
foreach my $VAL (@ROW){
|
||||
undef %ds_list;
|
||||
$ds_list{$fh} = $fh;
|
||||
write_to_files($rowstart."<v>".$VAL."</v></row>\n");
|
||||
$fh++;
|
||||
}
|
||||
next;
|
||||
}
|
||||
if(m/<ds>/){
|
||||
$inside_ds_block = 1;
|
||||
undef %ds_list;
|
||||
$ds_list{$tmpds} = $tmpds;
|
||||
write_to_files($d);
|
||||
$tmpds++;
|
||||
next;
|
||||
}
|
||||
if(m/<cdp_prep>/){
|
||||
write_to_files($d);
|
||||
$inside_ds_block = 0;
|
||||
$tmpds = 1;
|
||||
%ds_list = %original_ds_list;
|
||||
next;
|
||||
}
|
||||
if(m/<\/ds>/){
|
||||
write_to_files($d);
|
||||
$inside_ds_block = 0;
|
||||
# write to all files alter </ds>
|
||||
%ds_list = %original_ds_list;
|
||||
next;
|
||||
}
|
||||
if(m/<\/database>/){
|
||||
# write to all files alter </database>
|
||||
%ds_list = %original_ds_list;
|
||||
write_to_files($d);
|
||||
next;
|
||||
}
|
||||
if($inside_ds_block == 1){
|
||||
# rename DS
|
||||
$d =~ s/<name>(.*)<\/name>/<name> 1 <\/name>/;
|
||||
}
|
||||
write_to_files($d);
|
||||
}
|
||||
close(XML);
|
||||
print "... done $i lines\n";
|
||||
unlink($tmpfile);
|
||||
}
|
||||
|
||||
#
|
||||
# Parse process_perfdata.cfg
|
||||
#
|
||||
sub parse_config {
|
||||
my $config_file = shift;
|
||||
my $line = 0;
|
||||
if( ! -e $config_file ){
|
||||
print "$config_file not found\n";
|
||||
exit;
|
||||
}
|
||||
if ( -e $config_file ) {
|
||||
open CFG, '<', "$config_file";
|
||||
while (<CFG>) {
|
||||
$line++;
|
||||
chomp;
|
||||
s/ //g;
|
||||
next if /^#/;
|
||||
next if /^$/;
|
||||
s/#.*//;
|
||||
|
||||
if (/^(.*)=(.*)$/) {
|
||||
if ( defined $conf{$1} ) {
|
||||
$conf{$1} = $2;
|
||||
}
|
||||
}
|
||||
}
|
||||
close CFG;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Change RRD_STORAGE_TYPE to MULTIPLE
|
||||
#
|
||||
sub change_config {
|
||||
my $cfg_file = $conf{'CFG_DIR'}."/process_perfdata.cfg";
|
||||
my $error = system("sed -i -e ".'s/\s*RRD_STORAGE_TYPE\s*=\s*SINGLE/RRD_STORAGE_TYPE=MULTIPLE/i'." $cfg_file");
|
||||
}
|
||||
|
||||
sub check_storage_type{
|
||||
if($conf{'RRD_STORAGE_TYPE'} eq "MULTIPLE"){
|
||||
print "RRD_STORAGE_TYPE is already set to ".$conf{'RRD_STORAGE_TYPE'}."\n";
|
||||
}
|
||||
}
|
||||
sub check_custom_template {
|
||||
my $command = $opt_c;
|
||||
if ( $conf{DRY_RUN} == 1 ){
|
||||
print "No config check while DRY_RUN = 1\n";
|
||||
return;
|
||||
}
|
||||
if ( $command eq "ALL" ){
|
||||
return;
|
||||
}
|
||||
my $config_file = $conf{'CFG_DIR'}."/check_commands/".$command.".cfg";
|
||||
my $storage_type = "MULTIPLE";
|
||||
if ( -e $config_file && $conf{'FORCE'} == 0 ) {
|
||||
print "\nConfig for command $command does already exist ($config_file)\n\n";
|
||||
exit 0;
|
||||
}
|
||||
}
|
||||
|
||||
sub write_custom_template {
|
||||
my $command = $opt_c;
|
||||
if ( $conf{DRY_RUN} == 1 ){
|
||||
print "No config check while DRY_RUN = 1\n";
|
||||
return;
|
||||
}
|
||||
if ( $opt_c eq "ALL"){
|
||||
change_config();
|
||||
return;
|
||||
}
|
||||
my $config_file = $conf{'CFG_DIR'}."/check_commands/".$command.".cfg";
|
||||
my $storage_type = "MULTIPLE";
|
||||
open(CFG, ">", $config_file);
|
||||
print CFG "# Generated by rrd_convert.pl @PKG_VERSION@\n";
|
||||
print CFG "RRD_STORAGE_TYPE = MULTIPLE\n";
|
||||
close(CFG);
|
||||
if ( -s $config_file ) {
|
||||
print "\nConfig for command $command created ($config_file)\n";
|
||||
}
|
||||
}
|
||||
sub read_choice{
|
||||
my $question = shift;
|
||||
print $question.":";
|
||||
my $answer = <STDIN>;
|
||||
chomp $answer;
|
||||
return $answer;
|
||||
}
|
||||
|
||||
|
||||
sub print_help{
|
||||
print "Usage: $0 --check_command=<nagios_check_command>\n";
|
||||
print " --cfg_dir=<path_to_pnp_etc_dir>\n";
|
||||
print " [ --list_commands ]\n";
|
||||
print " [ --dry-run ]\n";
|
||||
print " [ --tmp_dir=<temp directory> ]\n";
|
||||
print " [ --no_structure_check ]\n";
|
||||
print "\n";
|
||||
print "This script is used to switch to RRD_STORAGE_TYPE = MULTIPLE for a given Nagios Check Command\n";
|
||||
print "More info online http://docs.pnp4nagios.org/pnp-0.6/rrd_convert\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
sub print_help_opt_p{
|
||||
print "\n";
|
||||
print "--cfg_dir not set\n";
|
||||
print "Please provide the path to your PNP4Nagios config directory\n";
|
||||
print "\n";
|
||||
print_help();
|
||||
}
|
||||
|
||||
sub print_version{
|
||||
print "Version @PKG_VERSION@\n";
|
||||
exit;
|
||||
}
|
||||
282
scripts/rrd_modify.pl.in
Normal file
282
scripts/rrd_modify.pl.in
Normal file
@@ -0,0 +1,282 @@
|
||||
#!@PERL@ -w
|
||||
# nagios: -epn
|
||||
## @PKG_NAME@–@PKG_VERSION@
|
||||
#
|
||||
# Copyright (c) 2012 PNP4Nagios Developer Team (http://www.pnp4nagios.org)
|
||||
#
|
||||
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
|
||||
# There are several Perl modules out there on www.cpan.org which allow adding
|
||||
# columns to an RRD file, so if this one doesn't fit your needs please have
|
||||
# a look there.
|
||||
# Please report any errors nevertheless.
|
||||
# See http://docs.pnp4nagios.org/pnp-0.6/about#support for details.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# you may have to adapt the path to your environment
|
||||
my $rrdtool = "@RRDTOOL@";
|
||||
# set to 1 if using PNP4Nagios where data source names are numerical
|
||||
my $PNP = 1;
|
||||
|
||||
### ---------------------------------------- ###
|
||||
### no user servicable parts below this line ###
|
||||
|
||||
my $pgm = "rrd_modify.pl";
|
||||
my $version = "0.01";
|
||||
my $legal = "Copyright (c) 2012 PNP4Nagios Developer Team (http://www.pnp4nagios.org)";
|
||||
|
||||
my ($rrd,$action,$columns,$type) = @ARGV;
|
||||
# valid actions
|
||||
my %action = (insert => 1, delete => 2);
|
||||
# valid data types
|
||||
my %type = (GAUGE => 1, COUNTER => 2, DERIVE => 3, ABSOLUTE => 4, COMPUTE => 5);
|
||||
# xml tags within cdp_prep
|
||||
my @cdp = ('primary_value','secondary_value','value',
|
||||
'unknown_datapoints','seasonal','last_seasonal',
|
||||
'init_flag','intercept','last_intercept',
|
||||
'slope','last_slope','nan_count','last_nan_count');
|
||||
|
||||
my @ds = (); # number of data sources within the rrd file
|
||||
my $out = 1; # output lines to file
|
||||
my $sign = "."; # decimal sign (locale dependent)
|
||||
my %xml = (); # lines within ds structure
|
||||
|
||||
# <rrd file> <action> <start column> defined?
|
||||
if ($#ARGV < 2) {
|
||||
usage();
|
||||
exit 1;
|
||||
}
|
||||
|
||||
die "$rrd does not exist\n" unless (-f $rrd);
|
||||
die "$rrd is not readable\n" unless (-r $rrd);
|
||||
die "$rrd is not writable\n" unless (-w $rrd);
|
||||
die "$rrdtool is a directory\n" if (-d $rrdtool);
|
||||
die "$rrdtool does not exist\n" unless (-f $rrdtool);
|
||||
die "$rrdtool is not executable\n" unless (-x $rrdtool);
|
||||
|
||||
$action = lc($action);
|
||||
unless (exists($action{$action})) {
|
||||
print "ERROR: action $action is not valid\n\n";
|
||||
usage();
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my ($start,$no) = split(/,/,$columns);
|
||||
$no = 1 unless (defined $no);
|
||||
# determine the number of data sources
|
||||
my $ds = `$rrdtool info $rrd | grep '^ds' | grep 'value' | wc -l`;
|
||||
# determine the decimal sign
|
||||
$sign = `$rrdtool info $rrd | grep '^ds' | grep 'value' | tail -1`;
|
||||
($sign) = $sign =~ /.* \d(.)\d+/;
|
||||
my $end = ($action eq "insert" ? $ds+$no : $ds);
|
||||
if (($start < 1) or ($start > $ds + 1)) {
|
||||
print "ERROR: number ($start) must be within 1..".($ds+1)."\n";
|
||||
exit 2;
|
||||
}
|
||||
|
||||
# check / set type of data source to be created
|
||||
if ($action eq "insert") {
|
||||
if (defined $type) {
|
||||
$type = uc($type);
|
||||
unless (exists($type{$type})) {
|
||||
print "ERROR: type $type is not valid\n\n";
|
||||
usage();
|
||||
exit 3;
|
||||
}
|
||||
} else {
|
||||
$type = "GAUGE";
|
||||
}
|
||||
}
|
||||
|
||||
# names of temporary/output files
|
||||
my $tmp1 = "$rrd.in";
|
||||
my $tmp2 = "$rrd.out";
|
||||
my $cmd = "$rrdtool dump $rrd > $tmp1";
|
||||
my $erg = system("$cmd");
|
||||
print "$cmd: RC=$erg\n" if ($erg);
|
||||
|
||||
processing ("$rrd");
|
||||
|
||||
$cmd = "$rrdtool restore $tmp2 $rrd.chg";
|
||||
$erg = system("$cmd");
|
||||
print "$cmd: RC=$erg\n" if ($erg);
|
||||
unlink "$tmp1";
|
||||
unlink "$tmp2";
|
||||
exit;
|
||||
|
||||
### some sub routines
|
||||
|
||||
sub processing {
|
||||
open (IFILE, "$tmp1") || die "error during open of $tmp1, RC=$!\n";
|
||||
open (OFILE, ">$tmp2") || die "error during create of $tmp2, RC=$!\n";
|
||||
while (<IFILE>) {
|
||||
my $tmp = $_;
|
||||
if (/<ds>/) {
|
||||
$out = 0;
|
||||
%xml = ();
|
||||
next;
|
||||
}
|
||||
if (/<\/ds>/) {
|
||||
my %tmp = %xml;
|
||||
push @ds, \%tmp;
|
||||
next;
|
||||
}
|
||||
if ((m|Round Robin Archives|) or (m|</cdp_prep>|)) {
|
||||
$out = 1;
|
||||
if ($action eq "insert") {
|
||||
my @save = splice(@ds,$start-1);
|
||||
for (1..$no) {
|
||||
my %xml = (@save) ? %{$save[0]} : %{$ds[0]};
|
||||
$xml{name} = $start+$_-1;
|
||||
# set defaults
|
||||
if (m|Round Robin Archives|) {
|
||||
$xml{last_ds} = "U";
|
||||
$xml{value} = "0${sign}0000000000e+00";
|
||||
$xml{unknown_sec} = 0;
|
||||
} else {
|
||||
$xml{primary_value} = "0${sign}0000000000e+00";
|
||||
$xml{secondary_value} = "0${sign}0000000000e+00";
|
||||
$xml{value} = "NaN" if (exists $xml{value});
|
||||
$xml{unknown_datapoints} = 0 if (exists $xml{unknown_datapoints});
|
||||
$xml{init_flag} = 1 if (exists $xml{init_flag});
|
||||
$xml{seasonal} = "NaN" if (exists $xml{seasonal});
|
||||
$xml{last_seasonal} = "NaN" if (exists $xml{last_seasonal});
|
||||
$xml{intercept} = "NaN" if (exists $xml{intercept});
|
||||
$xml{last_intercept} = "NaN" if (exists $xml{last_intercept});
|
||||
$xml{slope} = "NaN" if (exists $xml{slope});
|
||||
$xml{last_slope} = "NaN" if (exists $xml{last_slope});
|
||||
$xml{nan_count} = 1 if (exists $xml{nan_count});
|
||||
$xml{last_nan_count} = 1 if (exists $xml{last_nan_count});
|
||||
}
|
||||
push @ds,\%xml;
|
||||
}
|
||||
push @ds,@save;
|
||||
} else {
|
||||
my @save = splice(@ds,$start-1,$no);
|
||||
if ($PNP) { # renumber data source names
|
||||
for my $idx ($start..$end-$no) {
|
||||
$ds[$idx-1]->{name} = $idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m|Round Robin Archives|) {
|
||||
out_ds1();
|
||||
} else {
|
||||
out_ds2();
|
||||
}
|
||||
print OFILE $tmp;
|
||||
@ds = ();
|
||||
next;
|
||||
}
|
||||
if (/<row>/) {
|
||||
row($_);
|
||||
next;
|
||||
}
|
||||
# value enclosed in XML tags
|
||||
if (/<(\S+)>\s+(\S+)\s+</) {
|
||||
$xml{$1} = $2;
|
||||
}
|
||||
next unless ($out);
|
||||
print OFILE $tmp;
|
||||
}
|
||||
close (IFILE);
|
||||
close (OFILE);
|
||||
}
|
||||
|
||||
sub row {
|
||||
my $in = shift;
|
||||
my ($line,$r) = $in =~ /(.*<row>)(.*)<\/row>/;
|
||||
for (1..$start-1) {
|
||||
if ($r =~ s#^(<v>.*?</v>)##) {
|
||||
$line .= $1;
|
||||
}
|
||||
}
|
||||
for ($start..$start+$no-1) {
|
||||
if ($action eq "insert") {
|
||||
$line .= "<v> NaN </v>";
|
||||
} else {
|
||||
$r =~ s#^(<v>.*?</v>)##;
|
||||
}
|
||||
}
|
||||
for ($start+$no..$end) {
|
||||
if ($r =~ s#^(<v>.*?</v>)##) {
|
||||
$line .= $1;
|
||||
}
|
||||
}
|
||||
$line .= "</row>\n";
|
||||
print OFILE $line;
|
||||
}
|
||||
|
||||
sub out_ds1 {
|
||||
for (0..$#ds) {
|
||||
print OFILE <<EOD;
|
||||
\t<ds>
|
||||
\t\t<name> $ds[$_]->{name} </name>
|
||||
\t\t<type> $ds[$_]->{type} </type>
|
||||
\t\t<minimal_heartbeat> $ds[$_]->{minimal_heartbeat} </minimal_heartbeat>
|
||||
\t\t<min> $ds[$_]->{min} </min>
|
||||
\t\t<max> $ds[$_]->{max} </max>
|
||||
|
||||
\t\t<!-- PDP Status -->
|
||||
\t\t<last_ds> $ds[$_]->{last_ds} </last_ds>
|
||||
\t\t<value> $ds[$_]->{value} </value>
|
||||
\t\t<unknown_sec> $ds[$_]->{unknown_sec} </unknown_sec>
|
||||
\t</ds>
|
||||
|
||||
EOD
|
||||
}
|
||||
}
|
||||
|
||||
sub out_ds2 {
|
||||
for my $ds_no (0..$#ds) {
|
||||
print OFILE "\t\t\t<ds>\n";
|
||||
for my $tag (0..$#cdp) {
|
||||
print OFILE "\t\t\t<$cdp[$tag]> $ds[$ds_no]->{$cdp[$tag]} </$cdp[$tag]>\n" if (exists($ds[$ds_no]->{$cdp[$tag]}));
|
||||
}
|
||||
print OFILE "\t\t\t</ds>\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub usage {
|
||||
print <<EOD;
|
||||
|
||||
=== $pgm $version ===
|
||||
$legal
|
||||
|
||||
This script can be used to alter the number of data sources of an RRD file.
|
||||
|
||||
Usage:
|
||||
$pgm RRD_file insert|delete start_ds[,no_of_cols] [type]
|
||||
|
||||
Arguments:
|
||||
RRD_file
|
||||
the location of the RRD file. It will NOT be overwritten but appended
|
||||
by ".chg"
|
||||
insert or delete
|
||||
the operation to be executed
|
||||
start_ds
|
||||
the position at which the operation starts (1..no of data sources+1)
|
||||
no_of_cols
|
||||
(an optional) number of columns which will be added/deleted
|
||||
type
|
||||
the data type (one of GAUGE, COUNTER)
|
||||
Defaults to GAUGE if not specified for insert operations
|
||||
(DERIVE, ABSOLUTE, COMPUTE have not been tested and might result in
|
||||
errors during creation of a new RRD file)
|
||||
EOD
|
||||
}
|
||||
1009
scripts/verify_pnp_config_v2.pl
Executable file
1009
scripts/verify_pnp_config_v2.pl
Executable file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user