New upstream version 0.6.27

This commit is contained in:
geos_one
2025-08-06 18:11:51 +02:00
parent a6b4158f1f
commit 56a986c0ba
563 changed files with 45811 additions and 35282 deletions

13
scripts/.gitignore vendored Normal file
View File

@@ -0,0 +1,13 @@
# files generated from .in by configure
Makefile
rc.pnp_gearman_worker
check_pnp_rrds.pl
rc.npcd
rrd_convert.pl
rrd_modify.pl
npcd.service
pnp_gearman_worker.service
npcd.upstart
npcd.openrc
process_perfdata.pl
newbsd.npcd

View File

@@ -1,16 +1,28 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
LOGDIR=@localstatedir@
CFGDIR=@sysconfdir@
LOGDIR=@PNP_LOGDIR@
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@
PERFDATA_SPOOL_DIR=@PERFDATA_SPOOL_DIR@
INIT_TYPE=@init_type@
INIT_DIR=@initdir@
INIT_OPTS=@INIT_OPTS@
INIT_FILE=@initname@
SRC_INIT=@src_init@
INIT_PERM=@INIT_PERM@
HTTP_USER=@HTTP_USER@
HTTP_GRP=@HTTP_GROUP@
NAGIOS_USER=@nagios_user@
NAGIOS_GRP=@nagios_group@
MIX_OPTS=-o ${NAGIOS_USER} -g ${HTTP_GRP}
CP=@CP@
@@ -24,29 +36,43 @@ distclean: clean
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-init:
install-processperfdata:
$(INSTALL) -m 755 $(INSTALL_OPTS) process_perfdata.pl $(DESTDIR)$(LIBEXECDIR)
install-daemoninit: install-init
@if [ x$(INIT_TYPE) = xsysv ]; then \
if which chkconfig >/dev/null 2>&1; then \
chkconfig --add npcd; \
elif which update-rc.d >/dev/null 2>&1; then \
update-rc.d npcd defaults; \
fi \
elif [ x$(INIT_TYPE) = xsystemd ]; then \
if which systemctl >/dev/null 2>&1; then \
systemctl enable npcd.service ; \
fi; \
chmod 0644 $(INIT_DIR)/$(INIT_FILE); \
elif [ x$(INIT_TYPE) = xupstart ]; then \
if which initctl >/dev/null 2>&1; then \
initctl reload-configuration; \
fi \
elif [ x$(INIT_TYPE) = xopenrc ]; then \
if which rc-update >/dev/null 2>&1; then \
rc-update add npcd default; \
fi \
fi
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 2755 $(MIX_OPTS) -d $(DESTDIR)$(PERFDATADIR)
$(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBEXECDIR)
$(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(PERFDATA_SPOOL_DIR)
$(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LOGDIR)
$(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LOGDIR)/stats
$(MAKE) install-processperfdata
$(MAKE) install-plugins
$(MAKE) install-rrdconvert
$(MAKE) install-rrdmodify
$(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LOGDIR)/lock
$(INSTALL) -m 755 $(INIT_OPTS) -d $(DESTDIR)$(INIT_DIR)
$(INSTALL) -m $(INIT_PERM) $(INIT_OPTS) $(SRC_INIT) $(DESTDIR)$(INIT_DIR)/$(INIT_FILE)
$(INSTALL) -m 755 $(INSTALL_OPTS) process_perfdata.pl $(DESTDIR)$(LIBEXECDIR)
$(INSTALL) -m 755 $(INSTALL_OPTS) check_pnp_rrds.pl $(DESTDIR)$(LIBEXECDIR)
$(INSTALL) -m 755 $(INSTALL_OPTS) rrd_convert.pl $(DESTDIR)$(LIBEXECDIR)
$(INSTALL) -m 755 $(INSTALL_OPTS) rrd_modify.pl $(DESTDIR)$(LIBEXECDIR)

View File

@@ -40,11 +40,22 @@ my $opt_w = 1;
my $opt_c = 10;
my $opt_t = 10;
my $opt_p = "@PERFDATA_DIR@";
my $nagcfg = "@NAGIOS_CFG@";
open(NC,"<$nagcfg") || die "unable to read nagios cfg at $nagcfg";
my $opt_ncmd = "/usr/local/nagios/var/rw/nagios.cmd";
while (<NC>) {
next unless /^\s*command_file\s*=\s*(.*)/;
$opt_ncmd = $1;
last;
}
close(NC);
my $opt_phost = "";
my $opt_pservice = "";
my $opt_ignore;
my $VERSION = "@PKG_VERSION@";
my $VERSION = "@PACKAGE_VERSION@";
my $PROGNAME = basename($0);
my $PASV = 0;
my $USER = getpwuid($<);
@@ -278,7 +289,7 @@ sub print_usage () {
}
sub print_support {
print "SUPPORT: http://www.pnp4nagios.org/pnp/\n";
print "SUPPORT: https://github.com/pnp4nagios/pnp4nagios\n";
print "\n\n";
}

62
scripts/config4rpm_path.sh Executable file
View File

@@ -0,0 +1,62 @@
#!/bin/bash
# WHAT: Configure pnp4nagios to use rpm pkg's path, instead of /usr/local.
# WHY : To test new code locally without going through whole rpm creation/deployment workflow.
#
# Example output:
#*** Configuration summary for pnp4nagios-0.6.27 08-29-2023 ***
#
# General Options:
# ------------------------- -------------------
# Nagios user/group: nagios nagios
# Install directory: /usr
# HTML Dir: /usr/share/nagios/html/pnp4nagios
# Config Dir: /etc/pnp4nagios
# Location of rrdtool binary: /usr/bin/rrdtool Version 1.7.2
# RRDs Perl Modules: FOUND (Version 1.7002)
# RRD Files stored in: /var/lib/pnp4nagios
# process_perfdata.pl Logfile: /var/log/pnp4nagios/perfdata.log
# Perfdata files (NPCD) stored in: /var/spool/pnp4nagios
#
# Web Interface Options:
# ------------------------- -------------------
# HTML URL: http://localhost/pnp4nagios
# Apache Config File: /etc/httpd/conf.d/pnp4nagios.conf
#
#
# Review the options above for accuracy. If they look okay,
# type 'make all' to compile.
#
_name=pnp4nagios
_exec_prfix=/usr
_bindir=/usr/bin
_sbindir=/usr/sbin
_sysconfdir=/etc
_libexecdir=/usr/libexec
_libdir=/usr/lib64
_localstatedir=/var
_datadir=/usr/share
./configure --build=x86_64-redhat-linux-gnu \
--host=x86_64-redhat-linux-gnu \
--program-prefix= \
--prefix=${_exec_prfix} \
--exec-prefix=${_exec_prfix} \
--bindir=${_bindir} \
--sbindir=${_sbindir} \
--sysconfdir=${_sysconfdir} \
--datadir=${_datadir} \
--includedir=/usr/include \
--libdir=${_libexecdir} \
--libexecdir=${_libexecdir} \
--localstatedir=${_localstatedir} \
--sharedstatedir=/var/lib \
--mandir=/usr/share/man \
--infodir=/usr/share/info \
--libexecdir=/usr/libexec/${_name} \
--sysconfdir=/etc/${_name} \
--localstatedir=${_localstatedir}/log/${_name} \
--datadir=${_datadir}/nagios/html/${_name} \
--datarootdir=${_datadir}/nagios/html/${_name} \
--with-perfdata-dir=${_localstatedir}/lib/${_name} \
--with-perfdata-spool-dir=${_localstatedir}/spool/${_name}

32
scripts/newbsd.npcd.in Normal file
View File

@@ -0,0 +1,32 @@
#!/bin/sh
#
# $NetBSD: npcd.sh,v 1.6 2008/06/20 15:28:11 gdt Exp $
#
# PROVIDE: npcd
# REQUIRE: DAEMON
. /etc/rc.subr
name="@npcd_name@"
command="@bindir@/${name}"
piddir="@piddir@"
pidfile="${piddir}/${name}.pid"
config="@pkgsysconfdir@/${name}.cfg"
@npcd_name@_user=@nagios_user@
@npcd_name@_group=@nagios_grp@
command_args="-d -f $config"
required_files=$config
start_precmd="npcd_precmd"
npcd_precmd()
{
mkdir -p ${piddir}
chown @nagios_user@:@nagios_grp@ ${piddir}
}
load_rc_config $name
run_rc_command "$1"

61
scripts/npcd.openrc.in Normal file
View File

@@ -0,0 +1,61 @@
#!/sbin/openrc-run
# These two facilitate the bindir variable substitution below.
prefix=@prefix@
exec_prefix=@exec_prefix@
# This is a custom variable, and has the following default value if a
# specific config file is not defined by the user.
: ${NPCD_CONFIG:="@pkgsysconfdir@/npcd.cfg"}
: ${NAGIOS_CFG:="@NAGIOS_CFG@"}
# The rest are OpenRC variables.
extra_commands="checkconfig"
extra_started_commands="reload"
command="@bindir@/npcd"
command_args="-f ${NPCD_CONFIG}"
pidfile="@piddir@/npcd.pid"
verify="@pkgsysconfdir@/verify_pnp_config"
depend(){
use logger
after nagios
}
reload(){
checkconfig || return $?
ebegin "Reloading configuration"
start-stop-daemon --signal KILL --pidfile "${pidfile}"
eend $?
}
checkconfig(){
ebegin "Verifying config files"
# Save the output in case verification fails and errors are printed.
OUTPUT=$( ${verify} -m bulk+npcd -p "${NPCD_CONFIG}" -c "${NAGIOS_CFG}")
# Save the exit code from the verification so that `echo` doesn't
# clobber it. Then, if verification failed, show its
# output. Otherwise, succeed quietly.
local exit_code=$?
[ $exit_code -ne 0 ] && echo "${OUTPUT}" >&2
eend $exit_code
}
start_pre() {
# Without this, the "start" action will appear to succeed even if
# the config file contains errors, and the daemon fails to start.
# Another approach would be to wait for the PID file to appear, but
# this is fast enough and feels cleaner.
checkconfig || return $?
}
stop_pre() {
# If this is a restart, check to make sure the user's config
# isn't busted before we stop the running daemon.
if [ "${RC_CMD}" = "restart" ] ; then
checkconfig || return $?
fi
}

16
scripts/npcd.service.in Normal file
View File

@@ -0,0 +1,16 @@
[Unit]
Description=npcd rrd processor for pnp4nagios
Documentation=https://github.com/pnp4nagios/docs
After=network.target local-fs.target
[Service]
Type=exec
User=@nagios_user@
Group=@nagios_grp@
PIDFile=@piddir@/npcd.pid
Environment="CONFIG_FILE=@pkgsysconfdir@/npcd.cfg"
ExecStart=@bindir@/npcd -f ${CONFIG_FILE}
#ExecStop=/bin/kill -s QUIT $MAINPID
[Install]
WantedBy=@NAGIOS_UNIT@.service

21
scripts/npcd.upstart.in Normal file
View File

@@ -0,0 +1,21 @@
# pnp4nagios NPCD daemon for graphing Nagios data
description "pnp4nagios npcd daemon"
author "C. Lane lane@dchooz.org"
oom score never
start on (local-filesystems and net-device-up IFACE!=lo)
stop on runlevel [!2345]
reload signal SIGHUP
expect fork
respawn
pre-start script
@pkgsysconfdir@/verify_pnp_config -m bulk+npcd -p @pkgsysconfdir@/npcd.cfg -c @NAGIOS_CFG@
end script
exec @bindir@/npcd -f @pkgsysconfdir@/npcd.cfg

View File

@@ -0,0 +1,16 @@
[Unit]
Description=gearman rrd processor for pnp4nagios
Documentation=https://github.com/pnp4nagios/docs
After=network.target local-fs.target
[Service]
Type=exec
User=@nagios_user@
Group=@nagios_grp@
PIDFile=@piddir@/gearman_worker.pid
Environment="CONFIG_FILE=@pkgsysconfdir@/process_perfdata.cfg"
ExecStart="@libexecdir@/process_perfdata.pl --config=${CONFIG_FILE} --gearman --pidfile=@piddir@/gearman_worker.pid"
ExecStop=/bin/kill -s QUIT "$MAINPID"
[Install]
WantedBy=nagios.service

View File

@@ -1,6 +1,6 @@
#!@PERL@
# nagios: -epn
## @PKG_NAME@@PKG_VERSION@
## @PACKAGE_NAME@@PACKAGE_VERSION@
## Copyright (c) 2005-2015 Joerg Linge (http://www.pnp4nagios.org)
##
## This program is free software; you can redistribute it and/or
@@ -27,39 +27,45 @@ if( $< == 0 ){
use warnings;
use strict;
use POSIX;
use Fcntl;
use Getopt::Long;
use Time::HiRes qw(gettimeofday tv_interval);
use vars qw ( $TEMPLATE %NAGIOS $t0 $t1 $rt $delayed_write $rrdfile @ds_create $count $line $name $ds_update $dstype %CTPL);
use Time::HiRes qw(gettimeofday tv_interval usleep);
use vars qw ( $TEMPLATE %NAGIOS $t0 $t1 $delayed_write $rrdfile @ds_create $count $line $name $ds_update $dstype %CTPL %conf);
my %conf = (
%conf = (
TIMEOUT => 15,
CFG_DIR => "@sysconfdir@/",
CFG_DIR => "@pkgsysconfdir@/",
USE_RRDs => 1,
RRDPATH => "@PERFDATA_DIR@",
RRDTOOL => "@RRDTOOL@",
RRD_STORAGE_TYPE => "SINGLE",
RRD_HEARTBEAT => 8640,
RRA_STEP => 60,
RRA_CFG => "@sysconfdir@/rra.cfg",
STATS_DIR => "@localstatedir@/stats",
RRA_CFG => "@pkgsysconfdir@/rra.cfg",
STATS_DIR => "@PNP_LOGDIR@/stats",
LOCKDIR => "@PNP_LOGDIR@/lock/",
LOG_FILE => "@PERFDATA_LOG@",
LOG_FILE_MAX_SIZE => "10485760", #Truncate after 10MB
LOG_LEVEL => @DEBUG@,
LOG_LEVEL => @DEBUG_LEVEL@,
MAXLOCK => 30*60, # kill older locks
XML_ENC => "UTF-8",
XML_UPDATE_DELAY => 0, # Write XML only if file is older then XML_UPDATE_DELAY seconds
RRD_DAEMON_OPTS => "",
GEARMAN_HOST => "localhost:4730", # How many gearman worker childs to start
PREFORK => 2, # How many gearman worker childs to start
GEARMAN_HOST => "localhost:4730", # How many gearman worker childs to start
PREFORK => 2, # How many gearman worker childs to start
REQUESTS_PER_CHILD => 20000, # Restart after a given count of requests
ENCRYPTION => 1, # Decrypt mod_gearman packets
KEY => 'should_be_changed',
KEY_FILE => '@sysconfdir@/secret.key',
KEY_FILE => '@pkgsysconfdir@/secret.key',
UOM2TYPE => { 'c' => 'DERIVE', 'd' => 'DERIVE' },
IGNORE_HOST_PATTERN => '',
IGNORE_SERVICE_PATTERN => '',
IGNORE_LABEL_PATTERN => '',
);
my %const = (
XML_STRUCTURE_VERSION => "@XML_STRUCTURE_VERSION@",
VERSION => "@PKG_VERSION@",
VERSION => "@PACKAGE_VERSION@",
);
#
@@ -114,7 +120,7 @@ if ( $conf{USE_RRDs} == 1 ) {
}
#
# Include Gearman modules if needed
# Include Gearman modules if needed
#
if ( defined($opt_gm) ) {
unless ( eval "use Gearman::Worker;1" ) {
@@ -137,9 +143,9 @@ print_version() if ($opt_V);
# Use the timeout specified on the command line and if none use what is in the configuration
# If timeout is not in command line or the config file use the default
$opt_t = $conf{TIMEOUT} if ( $opt_t == $opt_t_default && $opt_t != $conf{TIMEOUT} );
print_log( "Default Timeout: $opt_t_default secs.", 2 );
print_log( "Config Timeout: $conf{TIMEOUT} secs.", 2 );
print_log( "Actual Timeout: $opt_t secs.", 2 );
print_log( "INFO: Default Timeout: $opt_t_default secs.", 2 );
print_log( "INFO: Config Timeout: $conf{TIMEOUT} secs.", 2 );
print_log( "INFO: Actual Timeout: $opt_t secs.", 2 );
init_signals();
my %children = (); # keys are current child process IDs
@@ -160,7 +166,7 @@ if( ! defined($opt_gm) ){
if($conf{ENCRYPTION} == 1){
print_log( "Encryptions is enabled", 0 );
read_keyfile($conf{'KEY_FILE'});
# fill key up to 32 bytes
# fill key up to 32 bytes
$conf{'KEY'} = substr($conf{'KEY'},0,32) . chr(0) x ( 32 - length( $conf{'KEY'} ) );
$cypher = Crypt::Rijndael->new( $conf{'KEY'}, Crypt::Rijndael::MODE_ECB() );
}
@@ -173,8 +179,7 @@ if( ! defined($opt_gm) ){
# Main function to switch to the right mode.
sub main {
my $job = shift;
my $t0 = [gettimeofday];
my $t1;
$t0 = [gettimeofday];
my $rt;
my $lines = 0;
# Gearman Worker
@@ -182,8 +187,7 @@ sub main {
print_log( "Gearman Worker Job start", 1 );
%NAGIOS = parse_env($job->arg);
$lines = process_perfdata();
$t1 = [gettimeofday];
$rt = tv_interval $t0, $t1;
$rt = tv_interval($t0, [gettimeofday]);
$stats{runtime} += $rt;
$stats{rows}++;
if( ( int $stats{timet} / 60 ) < ( int time / 60 )){
@@ -209,16 +213,16 @@ sub main {
$lines = process_perfdata_stdin();
} else {
# Synchronous mode
$opt_t = 5 if $opt_t > 5; # maximum timeout
$opt_t = 5 if $opt_t > 5; # maximum timeout
alarm($opt_t);
print_log( "process_perfdata.pl-$const{VERSION} starting in SYNC Mode", 1 );
%NAGIOS = parse_env();
$lines = process_perfdata();
}
$rt = tv_interval $t0, $t1;
$rt = tv_interval($t0, [gettimeofday]);
$stats{runtime} = $rt;
$stats{rows} = $lines;
store_internals();
store_internals() if $lines > 0;
print_log( "PNP exiting (runtime ${rt}s) ...", 1 );
exit 0;
}
@@ -257,7 +261,7 @@ sub parse_env {
if ( ( !$ENV{NAGIOS_HOSTNAME} ) and ( !$ENV{ICINGA_HOSTNAME} ) ) {
print_log( "Cant find Nagios Environment. Exiting ....", 1 );
exit 2;
exit 22;
}
foreach my $key ( sort keys %ENV ) {
if ( $key =~ /^(NAGIOS|ICINGA)_(.*)/ ) {
@@ -296,6 +300,7 @@ sub process_perfdata {
$stats{skipped}++;
return 1;
}
if ( ! defined($NAGIOS{PERFDATA}) && ! defined($opt_gm) ) {
print_log( "No Performance Data for $NAGIOS{HOSTNAME} / $NAGIOS{SERVICEDESC} ", 1 );
if ( !$opt_b && !$opt_s ) {
@@ -304,6 +309,20 @@ sub process_perfdata {
}
}
# Check if we want to ignore the host
my $pattern = $conf{IGNORE_HOST_PATTERN};
if ( $pattern ne '' && $NAGIOS{HOSTNAME} =~ /$pattern/) {
print_log( "Ignoring host due to a pattern: $NAGIOS{HOSTNAME}", 1 );
next;
}
# Check if we want to ignore the service
$pattern = $conf{IGNORE_SERVICE_PATTERN};
if ( $pattern ne '' && $NAGIOS{SERVICEDESC} =~ /$pattern/) {
print_log( "Ignoring service due to a pattern: $NAGIOS{SERVICEDESC}", 1 );
next;
}
if ( $NAGIOS{PERFDATA} =~ /^(.*)\s\[(.*)\]$/ ) {
$NAGIOS{PERFDATA} = $1;
$NAGIOS{CHECK_COMMAND} = $2;
@@ -329,50 +348,71 @@ sub process_perfdata_file {
if ( $opt_b =~ /-PID-(\d+)/ ) {
print_log( "Oops: $opt_b already processed by $1 - please check timeout settings", 0 );
}
# no file?
if (! -e "$opt_b") {
print_log( "ERROR: File $opt_b not found", 1 );
return 0;
}
GetLock('file1.lock',10,0.2);
# empty file?
my $n = (stat($opt_b))[7];
if (!defined($n) || $n == 0) {
print_log("empty file $opt_b",2);
if ($opt_b !~ /\-perfdata$/) {
my $iss = unlink $opt_b;
print_log("deleting $opt_b, OK=$iss",3);
}
ReleaseLock('file1.lock');
return 0;
}
print_log( "searching for $opt_b", 2 );
if ( -e "$opt_b" ) {
my $pdfile = "$opt_b" . "-PID-" . $$;
print_log( "renaming $opt_b to $pdfile for bulk update", 2 );
unless ( rename "$opt_b", "$pdfile" ) {
print_log( "ERROR: rename $opt_b to $pdfile failed", 1 );
exit 4;
}
print_log( "reading $pdfile for bulk update", 2 );
open( PDFILE, "< $pdfile" );
my $count = 0;
while (<PDFILE>) {
my $job_data = $_;
$count++;
print_log( "Processing Line $count", 2 );
my @LINE = split(/\t/);
%NAGIOS = (); # cleaning %NAGIOS Hash
#foreach my $k (@LINE) {
# $k =~ /([A-Z 0-9_]+)::(.*)$/;
# $ENV{ 'NAGIOS_' . $1 } = $2 if ($2);
#}
parse_env($job_data);
if ( $NAGIOS{SERVICEPERFDATA} || $NAGIOS{HOSTPERFDATA} ) {
process_perfdata();
} else {
print_log( "No Perfdata. Skipping line $count", 2 );
$stats{skipped}++;
}
}
print_log( "$count lines processed", 1 );
if ( unlink("$pdfile") == 1 ) {
print_log( "$pdfile deleted", 1 );
}else {
print_log( "Could not delete $pdfile:$!", 1 );
}
return $count;
my $pdfile = "$opt_b" . "-PID-" . $$;
print_log( "renaming $opt_b to $pdfile for bulk update", 2 );
unless ( rename "$opt_b", "$pdfile" ) {
print_log( "ERROR: rename $opt_b to $pdfile failed", 1 );
ReleaseLock('file1.lock');
exit 4;
}
else {
print_log( "ERROR: File $opt_b not found", 1 );
ReleaseLock('file1.lock');
# make a new empty file for Nagios to fill
if ($opt_b =~ /\-perfdata$/) {
my $tmpfh;
print_log("create new, empty $opt_b file",3);
if (!sysopen($tmpfh, $opt_b,O_WRONLY|O_CREAT|O_EXCL,0644)) {
print_log("failed to make new $opt_b",1);
}
close($tmpfh);
}
print_log( "reading $pdfile for bulk update", 2 );
open( PDFILE, "< $pdfile" );
my $count = 0;
while (<PDFILE>) {
my $job_data = $_;
$count++;
print_log( "Processing Line $count", 2 );
my @LINE = split(/\t/);
%NAGIOS = (); # cleaning %NAGIOS Hash
parse_env($job_data);
if ( $NAGIOS{SERVICEPERFDATA} || $NAGIOS{HOSTPERFDATA} ) {
process_perfdata();
} else {
print_log( "No Perfdata. Skipping line $count", 2 );
$stats{skipped}++;
}
}
print_log( "$count lines processed", 1 );
if ( unlink("$pdfile") == 1 ) {
print_log( "$pdfile deleted", 1 );
}else {
print_log( "Could not delete $pdfile:$!", 1 );
}
return $count;
}
#
@@ -473,7 +513,7 @@ sub data2rrd {
$DS = 1;
# PNP 0.4.x Template compatibility
$NAGIOS{RRDFILE} = "";
#
$rrd_storage_type = "MULTIPLE";
$rrdfile = $conf{RRDPATH} . "/" . $data[$i]{hostname} . "/" . $data[$i]{servicedesc} . "_" . $data[$i]{name} . ".rrd";
@@ -630,7 +670,7 @@ sub open_template {
my $xmlfile = shift;
$delayed_write = 0;
if( -e $xmlfile ){
my $mtime = (stat($xmlfile))[9];
my $mtime = (stat(_))[9];
my $t = time();
my $age = ($t - $mtime);
if ( $age < $conf{'XML_UPDATE_DELAY'} ){
@@ -704,7 +744,7 @@ sub write_env_to_template {
}
#
# Recursive Template search
# Recursive Template search
#
sub adjust_template {
my $command = shift;
@@ -719,14 +759,14 @@ sub adjust_template {
COMMAND => $command,
TEMPLATE => $template,
DSTYPE => $dstype,
RRD_STORAGE_TYPE => $conf{'RRD_STORAGE_TYPE'},
RRD_STORAGE_TYPE => $conf{'RRD_STORAGE_TYPE'},
RRD_HEARTBEAT => $conf{'RRD_HEARTBEAT'},
USE_MIN_ON_CREATE => 0,
USE_MAX_ON_CREATE => 0,
);
read_custom_template ( );
#
#
if ( $CTPL{'TEMPLATE'} ne $initial_template ){
read_custom_template ( );
}
@@ -751,7 +791,7 @@ sub read_custom_template {
$dstype = $conf{'UOM2TYPE'}{$uom};
print_log( "DEBUG: DSTYPE adjusted to $dstype by UOM", 3 );
}else {
$dstype = 'GAUGE';
$dstype = 'GAUGE';
}
print_log( "DEBUG: RAW Command -> $command", 3 );
@@ -937,7 +977,7 @@ sub _parse {
"min" => $6,
"max" => $7
);
$p{label} =~ s/[&"']//g; # cleanup
$p{name} =~ s/["']//g; # cleanup
$p{name} =~ s/[\/\\]/_/g; # cleanup
@@ -996,7 +1036,7 @@ sub cleanup {
}
#
# Urlencode
# Urlencode
#
sub urlencode {
my $string = shift;
@@ -1173,6 +1213,14 @@ sub parse_perfstring {
@perfs = ();
last;
}
# Check if we want to ignore the perfdata by label
my $ignore_pattern = $conf{IGNORE_LABEL_PATTERN};
if ( $ignore_pattern ne '' && $p{label} =~ /$ignore_pattern/) {
print_log( "Ignoring perfdata label due to a pattern: $p{label}", 1 );
next;
}
%CTPL = adjust_template( $NAGIOS{CHECK_COMMAND}, $p{uom}, $count );
if ( $CTPL{'USE_MAX_ON_CREATE'} == 1 && defined $p{max} ) {
@@ -1259,24 +1307,29 @@ sub handle_signal {
#
if ( defined ( $opt_gm ) ){
if($signal eq "CHLD" && defined($opt_gm) ){
my $pid = waitpid(-1, &WNOHANG);
if($pid == -1){
print_log( "### no hanging child ###", 1 );
} elsif ( WIFEXITED($?)) {
print_log( "### child $pid exited ###", 1 );
$children--;
} else {
print_log( "### wrong signal ###", 1 );
$children--;
while(my $pid = waitpid(-1, &WNOHANG)) {
if($pid == -1){
print_log( "### no hanging child ###", 1 );
last;
} elsif ( WIFEXITED($?)) {
print_log( "### child $pid exited ###", 1 );
delete $children{$pid};
$children--;
} else {
print_log( "### wrong signal ###", 1 );
delete $children{$pid};
$children--;
}
$SIG{'CHLD'} = \&handle_signal;
}
$SIG{'CHLD'} = \&handle_signal;
return;
}
if($signal eq "INT" || $signal eq "TERM"){
local($SIG{CHLD}) = 'IGNORE'; # we're going to kill our children
kill $signal => keys %children;
print_log( "*** process_perfdata.pl terminated on signal $signal", 0 );
pidlock("remove");
exit; # clean up with dignity
exit 11; # clean up with dignity
}
print_log( "*** process_perfdata.pl received signal $signal (ignored)", 0 );
}else{
@@ -1292,11 +1345,13 @@ sub handle_signal {
}
if ($opt_b && !$opt_s ) {
my $pdfile = "$opt_b" . "-PID-" . $$;
if ( unlink("$pdfile") == 1 ) {
print_log( "*** TIMEOUT: $pdfile deleted", 0 );
}
else {
print_log( "*** TIMEOUT: Could not delete $pdfile:$!", 0 );
if ( -f $pdfile) {
if ( unlink("$pdfile") == 1 ) {
print_log( "*** TIMEOUT: $pdfile deleted", 0 );
}
else {
print_log( "*** TIMEOUT: Could not delete $pdfile:$!", 0 );
}
}
}
my $temp_file = "$conf{RRDPATH}/$NAGIOS{HOSTNAME}/$NAGIOS{SERVICEDESC}.xml.$$";
@@ -1304,7 +1359,7 @@ sub handle_signal {
unlink($temp_file);
}
$t1 = [gettimeofday];
$rt = tv_interval $t0, $t1;
my $rt = tv_interval $t0, $t1;
$stats{runtime} = $rt;
print_log( "*** Timeout while processing Host: \"$NAGIOS{HOSTNAME}\" Service: \"$NAGIOS{SERVICEDESC}\"", 0 );
print_log( "*** process_perfdata.pl terminated on signal $signal", 0 );
@@ -1329,7 +1384,8 @@ sub init_stats {
#
# Store some internal runtime infos
#
# adding locking, since host/service perfdata jobs conflict on this
#
sub store_internals {
if( ! -w $conf{'STATS_DIR'}){
print_log("*** ERROR: ".$conf{'STATS_DIR'}." is not writable or does not exist",0);
@@ -1337,7 +1393,7 @@ sub store_internals {
}
my $statsfile = $conf{'STATS_DIR'}."/".(int $stats{timet} / 60);
open( STAT, ">> $statsfile" ) or die "Cant create statistic file ", $!;
printf(STAT "%d %f %d %d %d %d %d %d\n", $stats{timet},$stats{runtime},$stats{rows},$stats{update},$stats{create},$stats{error},$stats{invalid},$stats{skipped});
printf(STAT "%d %f %d %d %d %d %d %d\n", $stats{timet},$stats{runtime},$stats{rows},$stats{update},$stats{create},$stats{error},$stats{invalid},$stats{skipped});
close(STAT);
check_internals();
}
@@ -1348,28 +1404,47 @@ sub store_internals {
sub check_internals {
my $file;
my @files;
if (!GetLock('stats',20,0.25)) {
print_log("ERROR: failed to get stats file lock, bailing",0);
return;
}
opendir(STATS, $conf{'STATS_DIR'});
while ( defined ( my $file = readdir STATS) ){
next if $file =~ /^\.\.?$/; # skip . and ..
next if $file =~ /-PID-/; # skip temporary files
next if $file == (int $stats{timet} / 60); # skip our current file
next if $file =~ /-PID-/; # skip temporary files
next if $file =~ /^\d+$/ && $file == (int $stats{timet} / 60); # skip our current file
push @files, $file;
}
read_internals(@files);
read_internals(@files); # releases lock after rename
}
#
# Read and aggregate files found by check_internals()
# Read and aggregate files found by check_internals()
#
sub read_internals {
my @files = @_;
my @chunks;
my @nfiles;
foreach my $file (sort { $a <=> $b} @files){
unless ( rename($conf{'STATS_DIR'}."/".$file, $conf{'STATS_DIR'}."/".$file."-PID-".$$) ){
print_log( "ERROR: renaming stats file " . $conf{'STATS_DIR'}."/".$file . " to " . $conf{'STATS_DIR'}."/".$file."-PID-".$$ . " failed", 1 );
my $curfile = $conf{'STATS_DIR'}."/".$file;
my $newfile = $conf{'STATS_DIR'}."/".$file."-PID-".$$;
unless ( -e $curfile) {
print_log("ERROR: stats file $curfile not found",1);
next;
}
unless ( rename($curfile, $newfile) ){
print_log( "ERROR: renaming stats file $curfile to $newfile failed", 1 );
next;
}
open( STAT, "< ".$conf{'STATS_DIR'}."/".$file."-PID-".$$ );
push(@nfiles,$newfile);
}
ReleaseLock('stats');
foreach my $newfile (@nfiles) {
print_log("DEBUG: processing stats file $newfile",3);
open( STAT, "< $newfile" );
%stats = (
timet => 0,
error => 0,
@@ -1381,10 +1456,11 @@ sub read_internals {
update => 0,
);
while(<STAT>){
#print_log("DEBUG: stat info: $_",3);
@chunks = split();
$stats{timet} = $chunks[0];
$stats{runtime} += $chunks[1];
$stats{rows} += $chunks[2];
$stats{rows} += $chunks[2];
$stats{update} += $chunks[3];
$stats{create} += $chunks[4];
$stats{error} += $chunks[5];
@@ -1392,25 +1468,25 @@ sub read_internals {
$stats{skipped} += $chunks[7];
}
close(STAT);
unlink($conf{'STATS_DIR'}."/".$file."-PID-".$$);
unlink($newfile);
process_internals();
}
}
#
#
#
#
sub process_internals {
my $last_rrd_dtorage_type = $conf{'RRD_STORAGE_TYPE'};
$conf{'RRD_STORAGE_TYPE'} = "MULTIPLE";
%NAGIOS = (
%NAGIOS = (
HOSTNAME => '.pnp-internal',
DISP_HOSTNAME => 'pnp-internal',
SERVICEDESC => 'runtime',
DISP_SERVICEDESC => 'runtime',
TIMET => $stats{timet},
TIMET => 'N', #$stats{timet},
DATATYPE => 'SERVICEPERFDATA',
CHECK_COMMAND => 'pnp-runtime',
PERFDATA => "runtime=".$stats{runtime}."s rows=".$stats{rows}." errors=".$stats{error}." invalid=".$stats{invalid}." skipped=".$stats{skipped} ." update=".$stats{update}. " create=".$stats{create}
PERFDATA => "runtime=".$stats{runtime}."s rows=".$stats{rows}." errors=".$stats{error}." invalid=".$stats{invalid}." skipped=".$stats{skipped} ." update=".$stats{update}. " create=".$stats{create}
);
parse_perfstring( $NAGIOS{PERFDATA} );
$conf{'RRD_STORAGE_TYPE'} = $last_rrd_dtorage_type;
@@ -1427,7 +1503,7 @@ sub daemonize {
open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!";
defined( my $pid = fork ) or die "Can't fork: $!";
exit if $pid;
exit 12 if $pid;
pidlock("create");
setsid or die "Can't start a new session: $!";
} else {
@@ -1459,9 +1535,9 @@ sub new_child {
$sigset = POSIX::SigSet->new(SIGINT);
sigprocmask(SIG_BLOCK, $sigset)
or die "Can't block SIGINT for fork: $!\n";
die "fork: $!" unless defined ($pid = fork);
if ($pid) {
# Parent records the child's birth and returns.
sigprocmask(SIG_UNBLOCK, $sigset)
@@ -1472,18 +1548,24 @@ sub new_child {
} else {
# Child can *not* return from this subroutine.
$SIG{INT} = 'DEFAULT'; # make SIGINT kill us as it did before
# empty children list so we won't kill siblings if one children dies
%children = ();
# do not delete pidfile if child exits
undef $opt_pidfile;
# unblock signals
sigprocmask(SIG_UNBLOCK, $sigset)
or die "Can't unblock SIGINT for fork: $!\n";
my $worker = Gearman::Worker->new();
my @job_servers = split(/,/, $conf{'GEARMAN_HOST'}); # allow multiple gearman job servers
my @job_servers = split(/,/, $conf{'GEARMAN_HOST'}); # allow multiple gearman job servers
$worker->job_servers(@job_servers);
$worker->register_function("perfdata", 2, sub { return main(@_); });
my %opt = (
on_complete => sub { $req++; },
stop_if => sub { if ( $req > $conf{'REQUESTS_PER_CHILD'} ) { return 1;}; }
$worker->register_function("perfdata", undef, sub { return main(@_); });
my %opt = (
on_complete => sub { $req++; },
stop_if => sub { if ( $req > $conf{'REQUESTS_PER_CHILD'} ) { return 1;}; }
);
print_log("connecting to gearmand '".$conf{'GEARMAN_HOST'}."'",0);
$worker->work( %opt );
@@ -1491,7 +1573,7 @@ sub new_child {
# this exit is VERY important, otherwise the child will become
# a producer of more and more children, forking yourself into
# process death.
exit;
exit 13;
}
}
#
@@ -1583,14 +1665,14 @@ sub print_help {
Hint the program, that it was invoked by NPCD
-c, --config
Optional process_perfdata config file
Default: @sysconfdir@/process_perfdata.cfg
Default: @pkgsysconfdir@/process_perfdata.cfg
Gearman Worker Options:
--gearman
--gearman
Start in Gearman worker mode
--daemon
Run as daemon
--pidfile=/var/run/process_perfdata.pid
--pidfile=/run/nagios/process_perfdata.pid
The pidfile used while running in as Gearman worker daemon
EOD
@@ -1606,3 +1688,60 @@ sub print_version {
exit 0;
}
# GetLock(file,ntries,WaitBetweenTries_usec)
# wait is in seconds if < 10
sub GetLock
{
my $lockfile = shift;
$lockfile = 'ppd.lock' unless defined $lockfile;
my $dlockfile = $conf{LOCKDIR}.$lockfile;
my $tries = shift;
$tries = 10 unless defined $tries;
$tries = 10 if $tries < 1;
my $wait = shift;
$wait = $wait * 1000000 if defined($wait) && $wait < 10;
$wait = 1000000 unless defined $wait;
my $FH;
my $madewhen;
while ($tries > 0) {
if (sysopen($FH,$dlockfile,O_WRONLY|O_CREAT|O_EXCL)) {
my $t = time();
print $FH "$t\n";
close($FH);
print_log("DEBUG: PID $$ got lock on $lockfile at $t",3);
return 1;
}
if (open($FH,"<$dlockfile")) {
while (<$FH>) {
chomp;
next if /^\s*$/;
$madewhen = $_ unless defined $madewhen;
}
close($FH);
next unless defined $madewhen;
my $dt = time() - $madewhen;
if ($dt > $conf{MAXLOCK}) {
print_log("DEBUG: old lock file $lockfile deleted",3);
unlink $dlockfile;
next;
}
}
$tries--;
print_log("DEBUG: PID $$ did not get lock on $lockfile, $tries remain",3);
usleep($wait);
}
print_log("WARN: PID $$ failed to get lock on $lockfile",1);
return 0;
}
sub ReleaseLock
{
my $lockfile = shift;
$lockfile = 'ppd.lock' unless defined $lockfile;
my $dlockfile = $conf{LOCKDIR}.$lockfile;
my $iss = unlink $dlockfile;
print_log("DEBUG: PID $$ release lock on $lockfile, OK=$iss",3);
}

View File

@@ -6,7 +6,7 @@
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: @PKG_NAME@ NPCD Daemon Version @PKG_VERSION@
# Short-Description: @PACKAGE_NAME@ NPCD Daemon Version @PACKAGE_VERSION@
# Description: Nagios Performance Data C Daemon
### END INIT INFO
@@ -16,12 +16,10 @@
#
servicename=@npcd_name@
prefix=@prefix@
exec_prefix=${prefix}
NpcdBin=@bindir@/@npcd_name@
NpcdCfgFile=@sysconfdir@/npcd.cfg
NpcdCfgFile=@pkgsysconfdir@/npcd.cfg
NpcdVarDir=@localstatedir@
NpcdRunFile=/var/run/npcd.pid
NpcdRunFile=@piddir@/npcd.pid
NpcdLockDir=/var/lock/subsys
NpcdLockFile=@npcd_name@
NpcdUser=@nagios_user@

View File

@@ -12,9 +12,9 @@
### END INIT INFO
DAEMON="@libexecdir@/process_perfdata.pl"
CFG="@sysconfdir@/process_perfdata.cfg"
CFG="@pkgsysconfdir@/process_perfdata.cfg"
NAME=pnp_gearman_worker
PIDFILE=@localstatedir@/${NAME}.pid
PIDFILE=@piddir@/${NAME}.pid
LOCKFILE=/var/lock/subsys/${NAME}
USER=@nagios_user@
USERID=`id -u`

View File

@@ -1,5 +1,5 @@
#!@PERL@
## @PKG_NAME@@PKG_VERSION@ rrd_convert.pl
## @PACKAGE_NAME@@PACKAGE_VERSION@ rrd_convert.pl
## Copyright (c) 2006-2015 Joerg Linge (http://www.pnp4nagios.org)
##
## This program is free software; you can redistribute it and/or
@@ -35,7 +35,7 @@ if( $< == 0 ){
#
my %conf = (
CFG_DIR => "@sysconfdir@/",
CFG_DIR => "@pkgsysconfdir@/",
RRDPATH => "@PERFDATA_DIR@",
RRDTOOL => "@RRDTOOL@",
LOG_LEVEL => 0,
@@ -567,7 +567,7 @@ sub write_custom_template {
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 "# Generated by rrd_convert.pl @PACKAGE_VERSION@\n";
print CFG "RRD_STORAGE_TYPE = MULTIPLE\n";
close(CFG);
if ( -s $config_file ) {
@@ -595,7 +595,7 @@ sub print_help{
print " [ --read=<file with XML filenames> ]\n";
print "\n";
print "This script is used to switch to RRD_STORAGE_TYPE = MULTIPLE for all RRDs/a given Nagios Check Command/single RRDs \n";
print "More info online http://docs.pnp4nagios.org/pnp-0.6/rrd_convert\n";
print "More info online https://github.com/pnp4nagios/docs/blob/main/pages/pnp-0.6/rrd_convert.txt\n";
exit;
}
@@ -608,6 +608,6 @@ sub print_help_opt_p{
}
sub print_version{
print "Version @PKG_VERSION@\n";
print "Version @PACKAGE_VERSION@\n";
exit;
}

View File

@@ -1,6 +1,6 @@
#!@PERL@ -w
# nagios: -epn
## @PKG_NAME@@PKG_VERSION@
## @PACKAGE_NAME@@PACKAGE_VERSION@
#
# Copyright (c) 2006-2015 PNP4Nagios Developer Team (http://www.pnp4nagios.org)
#
@@ -23,7 +23,7 @@
# 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.
# See https://github.com/pnp4nagios/pnp4nagios/issues for
use strict;
use warnings;

File diff suppressed because it is too large Load Diff