|
Packit |
3f632f |
#! /usr/bin/perl -w
|
|
Packit |
3f632f |
# -*- mode: cperl -*-
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
###################################################################
|
|
Packit |
3f632f |
# MRTG 2.17.7 Multi Router Traffic Grapher
|
|
Packit |
3f632f |
###################################################################
|
|
Packit |
3f632f |
# Created by Tobias Oetiker <tobi@oetiker.ch>
|
|
Packit |
3f632f |
# and Dave Rand <dlr@bungi.com>
|
|
Packit |
3f632f |
#
|
|
Packit |
3f632f |
# For individual Contributers check the CHANGES file
|
|
Packit |
3f632f |
#
|
|
Packit |
3f632f |
###################################################################
|
|
Packit |
3f632f |
#
|
|
Packit |
3f632f |
# Distributed under the GNU General Public License
|
|
Packit |
3f632f |
#
|
|
Packit |
3f632f |
###################################################################
|
|
Packit |
3f632f |
my @STARTARGS=($0,@ARGV);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
@main::DEBUG=qw();
|
|
Packit |
3f632f |
# DEBUG TARGETS
|
|
Packit |
3f632f |
# cfg - watch the config file reading
|
|
Packit |
3f632f |
# dir - directory mangeling
|
|
Packit |
3f632f |
# base - basic program flow
|
|
Packit |
3f632f |
# tarp - target parser
|
|
Packit |
3f632f |
# snpo - snmp polling
|
|
Packit |
3f632f |
# snpo2 - more snmp debug
|
|
Packit |
3f632f |
# coca - confcache operations
|
|
Packit |
3f632f |
# repo - track confcache repopulation
|
|
Packit |
3f632f |
# fork - forking view
|
|
Packit |
3f632f |
# time - some timing info
|
|
Packit |
3f632f |
# log - logging of data via rateup or rrdtool
|
|
Packit |
3f632f |
# eval - trace eval experssions
|
|
Packit |
3f632f |
# prof - add timeing info some interesting bits of code
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$main::GRAPHFMT="png";
|
|
Packit |
3f632f |
# There older perls tend to behave peculiar with
|
|
Packit |
3f632f |
# large integers ...
|
|
Packit |
3f632f |
require 5.005;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
use strict;
|
|
Packit |
3f632f |
# addon jpt
|
|
Packit |
3f632f |
BEGIN {
|
|
Packit |
3f632f |
# Automatic OS detection ... do NOT touch
|
|
Packit |
3f632f |
if ( $^O =~ /^(ms)?(dos|win(32|nt)?)/i ) {
|
|
Packit |
3f632f |
$main::OS = 'NT';
|
|
Packit |
3f632f |
$main::SL = '\\';
|
|
Packit |
3f632f |
$main::PS = ';';
|
|
Packit |
3f632f |
} elsif ( $^O =~ /^NetWare$/i ) {
|
|
Packit |
3f632f |
$main::OS = 'NW';
|
|
Packit |
3f632f |
$main::SL = '/';
|
|
Packit |
3f632f |
$main::PS = ';';
|
|
Packit |
3f632f |
} elsif ( $^O =~ /^VMS$/i ) {
|
|
Packit |
3f632f |
$main::OS = 'VMS';
|
|
Packit |
3f632f |
$main::SL = '.';
|
|
Packit |
3f632f |
$main::PS = ':';
|
|
Packit |
3f632f |
} elsif ( $^O =~ /^os2$/i ) {
|
|
Packit |
3f632f |
$main::OS = 'OS2';
|
|
Packit |
3f632f |
$main::SL = '/';
|
|
Packit |
3f632f |
$main::PS = ';';
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$main::OS = 'UNIX';
|
|
Packit |
3f632f |
$main::SL = '/';
|
|
Packit |
3f632f |
$main::PS = ':';
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ( $ENV{LANG} and $ENV{LANG} =~ /UTF.*8/i ){
|
|
Packit |
3f632f |
my $args = join " ", map { /\s/ ? "\"$_\"" : $_ } @ARGV;
|
|
Packit |
3f632f |
$args ||= "";
|
|
Packit |
3f632f |
print <
|
|
Packit |
3f632f |
-----------------------------------------------------------------------
|
|
Packit |
3f632f |
ERROR: Mrtg will most likely not work properly when the environment
|
|
Packit |
3f632f |
variable LANG is set to UTF-8. Please run mrtg in an environment
|
|
Packit |
3f632f |
where this is not the case. Try the following command to start:
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
env LANG=C ${0} $args
|
|
Packit |
3f632f |
-----------------------------------------------------------------------
|
|
Packit |
3f632f |
ERR
|
|
Packit |
3f632f |
exit 0;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
use FindBin;
|
|
Packit |
3f632f |
use lib "${FindBin::Bin}";
|
|
Packit |
3f632f |
use lib "${FindBin::Bin}${main::SL}..${main::SL}lib${main::SL}mrtg2";
|
|
Packit |
3f632f |
use Getopt::Long;
|
|
Packit |
3f632f |
use Math::BigFloat;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# search for binaries in the bin and bin/../lib directory
|
|
Packit |
3f632f |
use MRTG_lib "2.100016";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $NOW = timestamp;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $graphiteObj;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# $SNMP_Session::suppress_warnings = 2;
|
|
Packit |
3f632f |
use locales_mrtg "0.07";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Do not Flash Console Windows for the forked rateup process
|
|
Packit |
3f632f |
BEGIN {
|
|
Packit |
3f632f |
if ($^O eq 'MSWin32'){
|
|
Packit |
3f632f |
eval {local $SIG{__DIE__};require Win32; Win32::SetChildShowWindow(0)};
|
|
Packit |
3f632f |
warn "WARNING: $@\n" if $@;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$main::STARTTIME = time;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
%main::verified_rrd = ();
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($MRTG_lib::OS eq 'OS2') {
|
|
Packit |
3f632f |
# in daemon mode we will pause 3 seconds to be sure that parent died
|
|
Packit |
3f632f |
require OS2::Process;
|
|
Packit |
3f632f |
if (OS2::Process::my_type() eq 'DETACH') {sleep(3);}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($MRTG_lib::OS eq 'UNIX') {
|
|
Packit |
3f632f |
$SIG{INT} = $SIG{TERM} =
|
|
Packit |
3f632f |
sub { unlink ${main::Cleanfile}
|
|
Packit |
3f632f |
if defined $main::Cleanfile;
|
|
Packit |
3f632f |
unlink ${main::Cleanfile2}
|
|
Packit |
3f632f |
if defined $main::Cleanfile2;
|
|
Packit |
3f632f |
unlink ${main::Cleanfile3}
|
|
Packit |
3f632f |
if defined $main::Cleanfile3;
|
|
Packit |
3f632f |
warn "$NOW: ERROR: Bailout after SIG $_[0]\n";
|
|
Packit |
3f632f |
exit 1;
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
$SIG{HUP} = sub {
|
|
Packit |
3f632f |
unlink ${main::Cleanfile}
|
|
Packit |
3f632f |
if defined $main::Cleanfile;
|
|
Packit |
3f632f |
unlink ${main::Cleanfile2}
|
|
Packit |
3f632f |
if defined $main::Cleanfile2;
|
|
Packit |
3f632f |
unlink ${main::Cleanfile3}
|
|
Packit |
3f632f |
if defined $main::Cleanfile3;
|
|
Packit |
3f632f |
die "$NOW: ERROR: Bailout after SIG $_[0]\n";
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
END {
|
|
Packit |
3f632f |
local($?, $!);
|
|
Packit |
3f632f |
unlink ${main::Cleanfile} if defined $main::Cleanfile;
|
|
Packit |
3f632f |
unlink ${main::Cleanfile2} if defined $main::Cleanfile2;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
&mai;;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
exit(0);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
#### Functions ################################################
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
sub main {
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# read in the config file
|
|
Packit |
3f632f |
my @routers;
|
|
Packit |
3f632f |
my %cfg;
|
|
Packit |
3f632f |
my %rcfg;
|
|
Packit |
3f632f |
my %opts;
|
|
Packit |
3f632f |
my $EXITCODE = 0;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
GetOptions(\%opts, 'user=s', 'group=s', 'lock-file=s','confcache-file=s','logging=s', 'check', 'fhs', 'daemon', 'pid-file=s','debug=s', 'log-only') or die "Please use valid Options\n";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (defined $opts{debug}){
|
|
Packit |
3f632f |
@main::DEBUG = split /\s*,\s*/, $opts{debug};
|
|
Packit |
3f632f |
if (defined $SNMP_util::Debug){
|
|
Packit |
3f632f |
$SNMP_util::Debug = 1 if grep /^snpo2$/, @main::DEBUG;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if (grep /^prof$/, @main::DEBUG){
|
|
Packit |
3f632f |
require Time::HiRes;
|
|
Packit |
3f632f |
eval "sub gettimeofday() {return Time::HiRes::time()}";
|
|
Packit |
3f632f |
# note this will crash if the module is missing
|
|
Packit |
3f632f |
# so only use the --debug=prof if you have Time::HiRes installed
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
eval "sub gettimeofday() {return time()}";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
debug 'time', "prog start ".localtime(time);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $uid = $<;
|
|
Packit |
3f632f |
my $gid = $(;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (defined $opts{group}) {
|
|
Packit |
3f632f |
$gid = getgrnam($opts{group});
|
|
Packit |
3f632f |
die "$NOW: ERROR: Unknown Group: $opts{group})\n" if not defined $gid;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (defined $opts{user}) {
|
|
Packit |
3f632f |
$uid = getpwnam($opts{user});
|
|
Packit |
3f632f |
die "$NOW: ERROR: Unknown User: $opts{user})\n" if not defined $uid;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# If we've specified using FHS (http://www.pathname.com/fhs/) on the command line,
|
|
Packit |
3f632f |
# use the relevant path definitions (can be overridden later):
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $confcachefile;
|
|
Packit |
3f632f |
my $pidfile;
|
|
Packit |
3f632f |
my $lockfile;
|
|
Packit |
3f632f |
my $templock;
|
|
Packit |
3f632f |
my $logfile;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (defined $opts{"fhs"}) {
|
|
Packit |
3f632f |
$confcachefile = "/var/cache/mrtg/mrtg.ok";
|
|
Packit |
3f632f |
$pidfile = "/var/run/mrtg.pid";
|
|
Packit |
3f632f |
$lockfile = "/var/cache/mrtg/mrtg.lck";
|
|
Packit |
3f632f |
$templock = "/var/cache/mrtg/mrtg.lck.$$";
|
|
Packit |
3f632f |
$logfile = "/var/log/mrtg.log";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $cfgfile = shift @ARGV;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ( !defined $cfgfile and -r "/etc/mrtg.cfg" ) { $cfgfile = "/etc/mrtg.cfg"; }
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
printusage() unless defined $cfgfile;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# PID file code, used later if daemonizing...
|
|
Packit |
3f632f |
if ( !defined($pidfile) ) {
|
|
Packit |
3f632f |
$pidfile = $cfgfile;
|
|
Packit |
3f632f |
$pidfile =~ s/\.[^.\/]+$//;
|
|
Packit |
3f632f |
$pidfile .= '.pid';
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
$pidfile = $opts{"pid-file"} || $pidfile;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Run as a daemon, specified on command line (required for FHS compliant daemon)
|
|
Packit |
3f632f |
if (defined $opts{"daemon"}) {
|
|
Packit |
3f632f |
# Create a pidfile, then chown it so we can use it once we change user
|
|
Packit |
3f632f |
&create_pid($pidfile);
|
|
Packit |
3f632f |
chown $uid, $gid, $pidfile;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
($(,$)) = ($gid,$gid) ;
|
|
Packit |
3f632f |
($<,$>) = ($uid,$uid) ;
|
|
Packit |
3f632f |
die "$NOW: ERROR failed to set UID to $uid\n" unless ($< == $uid and $> == $uid);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$logfile = $opts{logging} || $logfile;
|
|
Packit |
3f632f |
if (defined $logfile){
|
|
Packit |
3f632f |
setup_loghandlers $logfile;
|
|
Packit |
3f632f |
warn "Started mrtg with config \'$cfgfile\'\n";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# lets make sure that there are not two mrtgs running in parallel.
|
|
Packit |
3f632f |
# so we lock on the cfg file. Nothing fancy, just a lockfile
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$lockfile = $opts{"lock-file"} || $lockfile;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (! defined $lockfile) {
|
|
Packit |
3f632f |
$lockfile = $cfgfile."_l";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if (! defined $templock) {
|
|
Packit |
3f632f |
$templock = $lockfile."_" . $$ ;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
debug('base', "Creating Lockfiles $lockfile,$templock");
|
|
Packit |
3f632f |
&lockit($lockfile,$templock);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
debug('base', "Reading Config File: $cfgfile");
|
|
Packit |
3f632f |
my $cfgfile_age = -M $cfgfile;
|
|
Packit |
3f632f |
readcfg($cfgfile,\@routers,\%cfg,\%rcfg);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
imggen($cfg{icondir} || $cfg{imagedir} || $cfg{workdir});
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Enable or disable snmpv3
|
|
Packit |
3f632f |
if(defined $cfg{enablesnmpv3}) {
|
|
Packit |
3f632f |
$cfg{enablesnmpv3} = lc($cfg{enablesnmpv3});
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$cfg{enablesnmpv3} = 'no';
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($cfg{threshmailserver}) {
|
|
Packit |
3f632f |
if (eval {local $SIG{__DIE__};require Net::SMTP;}) {
|
|
Packit |
3f632f |
import Net::SMTP;
|
|
Packit |
3f632f |
debug('base', "Loaded Net::SMTP module for ThreshMail.");
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
die "$NOW: WARNING: Can't load Net::SMTP module. This is required for ThreshMail.";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
# Check we have the necessary libraries for IPv6 support
|
|
Packit |
3f632f |
if ($cfg{enablesnmpv3} eq 'yes') {
|
|
Packit |
3f632f |
if (eval {local $SIG{__DIE__};require Net_SNMP_util;}) {
|
|
Packit |
3f632f |
import Net_SNMP_util;
|
|
Packit |
3f632f |
debug('base', "SNMP V3 libraries found, SNMP V3 enabled.");
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: SNMP V3 libraries not found, SNMP V3 disabled.\n";
|
|
Packit |
3f632f |
$cfg{enablesnmpv3} = 'no';
|
|
Packit |
3f632f |
require SNMP_util;
|
|
Packit |
3f632f |
import SNMP_util;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
else { # load V1/V2 libraries
|
|
Packit |
3f632f |
require SNMP_util;
|
|
Packit |
3f632f |
import SNMP_util;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Enable or disable IPv6
|
|
Packit |
3f632f |
if(defined $cfg{enableipv6}) {
|
|
Packit |
3f632f |
$cfg{enableipv6} = lc($cfg{enableipv6});
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$cfg{enableipv6} = 'no';
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Check we have the necessary libraries for IPv6 support
|
|
Packit |
3f632f |
if ($cfg{enableipv6} eq 'yes') {
|
|
Packit |
3f632f |
if ( eval {local $SIG{__DIE__};require Socket; require Socket6; require IO::Socket::INET6;}) {
|
|
Packit |
3f632f |
import Socket;
|
|
Packit |
3f632f |
import Socket6;
|
|
Packit |
3f632f |
debug('base', "IPv6 libraries found, IPv6 enabled.");
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: IPv6 libraries not found, IPv6 disabled.\n";
|
|
Packit |
3f632f |
$cfg{enableipv6} = 'no';
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Module invocation for sending a copy of the time series data to graphite.
|
|
Packit |
3f632f |
if(defined $cfg{sendtographite}) {
|
|
Packit |
3f632f |
require Net::Graphite;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# from our last run we kept some info about
|
|
Packit |
3f632f |
# the configuration of our devices around
|
|
Packit |
3f632f |
debug('base', "Reading Interface Config cache");
|
|
Packit |
3f632f |
$confcachefile = $opts{"confcache-file"} || $confcachefile;
|
|
Packit |
3f632f |
if ( !defined($confcachefile) ) {
|
|
Packit |
3f632f |
$confcachefile = $cfgfile;
|
|
Packit |
3f632f |
$confcachefile =~ s/\.[^.\/]+$//;
|
|
Packit |
3f632f |
$confcachefile .= ".ok";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
my $confcache = readconfcache($confcachefile);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Check the config and create the target object
|
|
Packit |
3f632f |
debug('base', "Checking Config File");
|
|
Packit |
3f632f |
my @target;
|
|
Packit |
3f632f |
cfgcheck(\@routers, \%cfg, \%rcfg, \@target, \%opts);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# exit here if we only check the config file
|
|
Packit |
3f632f |
# in case of an error, cfgcheck() already exited
|
|
Packit |
3f632f |
if (defined $opts{check}) {
|
|
Packit |
3f632f |
debug('base', "Remove Lock Files");
|
|
Packit |
3f632f |
close LOCK; unlink ($templock, $lockfile);
|
|
Packit |
3f632f |
debug('base', "Exit after successful config file check");
|
|
Packit |
3f632f |
exit 0;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# postload rrdtool support
|
|
Packit |
3f632f |
if ($cfg{logformat} eq 'rrdtool'){
|
|
Packit |
3f632f |
debug('base', "Loading RRD support");
|
|
Packit |
3f632f |
require 'RRDs.pm';
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# set the locale
|
|
Packit |
3f632f |
my $LOC;
|
|
Packit |
3f632f |
if ( $cfg{'language'} and defined($lang2tran::LOCALE{"\L$cfg{'language'}\E"})) {
|
|
Packit |
3f632f |
debug('base', "Loading Locale for ".$cfg{'language'});
|
|
Packit |
3f632f |
$LOC=$lang2tran::LOCALE{"\L$cfg{'language'}\E"};
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
debug('base', "Loading default Locale");
|
|
Packit |
3f632f |
$LOC=$lang2tran::LOCALE{'default'};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Daemon Code
|
|
Packit |
3f632f |
my $last_time=0;
|
|
Packit |
3f632f |
my $curent_time;
|
|
Packit |
3f632f |
my $sleep_time;
|
|
Packit |
3f632f |
if (defined $opts{"daemon"}) { $cfg{'runasdaemon'} = "yes"; }
|
|
Packit |
3f632f |
&demonize_me($pidfile,$cfgfile) if defined $cfg{'runasdaemon'} and $cfg{'runasdaemon'} =~ /y/i and $MRTG_lib::OS ne 'VMS'
|
|
Packit |
3f632f |
and not (defined $cfg{'nodetach'} and $cfg{'nodetach'} =~ /y/i);
|
|
Packit |
3f632f |
# auto restart on die if running as demon
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$SIG{__DIE__} = sub {
|
|
Packit |
3f632f |
warn $_[0];
|
|
Packit |
3f632f |
warn "*** Restarting after 10 seconds in an attempt to recover from the error above\n";
|
|
Packit |
3f632f |
sleep 10;
|
|
Packit |
3f632f |
exec @STARTARGS;
|
|
Packit |
3f632f |
} if $cfg{'runasdaemon'};
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
debug('base', "Starting main Loop");
|
|
Packit |
3f632f |
do { # Do this loop once for native mode and forever in daemon mode
|
|
Packit |
3f632f |
my $router;
|
|
Packit |
3f632f |
$NOW = timestamp; # get the time
|
|
Packit |
3f632f |
debug 'time', "loop start ".localtime(time);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
#if we run as daemon, we sleep in between collection cycles
|
|
Packit |
3f632f |
$sleep_time= (int($cfg{interval}*60))-(time-$last_time);
|
|
Packit |
3f632f |
if ($sleep_time > 0 ) { #If greater than 0 the sleep that amount of time
|
|
Packit |
3f632f |
debug('time', "Sleep time $sleep_time seconds");
|
|
Packit |
3f632f |
sleep ($sleep_time);
|
|
Packit |
3f632f |
} elsif ($last_time > 0) {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: data collection did not complete within interval!\n";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
$last_time=time;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# set meta expires if there is an index file
|
|
Packit |
3f632f |
# 2000/05/03 Bill McGonigle <bill@zettabyte.net>
|
|
Packit |
3f632f |
if (defined $cfg{'writeexpires'}) {
|
|
Packit |
3f632f |
my $exp = &expistr($cfg{'interval'});
|
|
Packit |
3f632f |
my $fil;
|
|
Packit |
3f632f |
$fil = "$cfg{'htmldir'}index.html" if -e "$cfg{'htmldir'}index.html";
|
|
Packit |
3f632f |
$fil = "$cfg{'htmldir'}index.htm" if -e "$cfg{'htmldir'}index.htm";
|
|
Packit |
3f632f |
if (defined $fil) {
|
|
Packit |
3f632f |
open(META, ">$fil.meta");
|
|
Packit |
3f632f |
print META "Expires: $exp\n";
|
|
Packit |
3f632f |
close(META);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Use SNMP to populate the target object
|
|
Packit |
3f632f |
debug('base', "Populate Target object by polling SNMP and".
|
|
Packit |
3f632f |
" external Datasources");
|
|
Packit |
3f632f |
debug 'time', "snmp read start ".localtime(time);
|
|
Packit |
3f632f |
readtargets($confcache,\@target, \%cfg);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$NOW = timestamp; # get the time
|
|
Packit |
3f632f |
# collect data for each router or pseudo target (`executable`)
|
|
Packit |
3f632f |
debug 'time', "target loop start ".localtime(time);
|
|
Packit |
3f632f |
foreach $router (@routers) {
|
|
Packit |
3f632f |
debug('base', "Act on Router/Target $router");
|
|
Packit |
3f632f |
if (defined $rcfg{'setenv'}{$router}) {
|
|
Packit |
3f632f |
my $line = $rcfg{'setenv'}{$router};
|
|
Packit |
3f632f |
while ( $line =~ s/([^=]+)=\"([^\"]*)\"\s*// ) # " - unconfuse the highliter
|
|
Packit |
3f632f |
{
|
|
Packit |
3f632f |
$ENV{$1}=$2;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
my($savetz) = $ENV{'TZ'};
|
|
Packit |
3f632f |
if (defined $rcfg{'timezone'}{$router}) {
|
|
Packit |
3f632f |
$ENV{'TZ'} = $rcfg{'timezone'}{$router};
|
|
Packit |
3f632f |
if ( $main::OS eq 'UNIX' ){
|
|
Packit |
3f632f |
require 'POSIX.pm';
|
|
Packit |
3f632f |
POSIX::tzset();
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my ($inlast, $outlast, $uptime, $name, $time) =
|
|
Packit |
3f632f |
getcurrent(\@target, $router, \%rcfg, \%cfg);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ( defined($inlast) and defined($outlast)) {
|
|
Packit |
3f632f |
$EXITCODE = $EXITCODE | 1;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
else {
|
|
Packit |
3f632f |
$EXITCODE = $EXITCODE | 2;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
debug('base', "Get Current values: in:".( defined $inlast ? $inlast : "undef").", out:".
|
|
Packit |
3f632f |
( defined $outlast? $outlast : "undef").", up:".
|
|
Packit |
3f632f |
( defined $uptime ? $uptime : "undef").", name:".
|
|
Packit |
3f632f |
( defined $name ? $name : "undef").", time:".
|
|
Packit |
3f632f |
( defined $time ? $time : "undef"));
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
#abort, if the router is not responding.
|
|
Packit |
3f632f |
if ($cfg{'logformat'} ne 'rrdtool') {
|
|
Packit |
3f632f |
# undefined values are ok for rrdtool !
|
|
Packit |
3f632f |
#if ( not defined $inlast or not defined $outlast){
|
|
Packit |
3f632f |
# warn "$NOW: WARNING: Skipping Update of $router, inlast is not defined\n"
|
|
Packit |
3f632f |
# unless defined $inlast;
|
|
Packit |
3f632f |
# warn "$NOW: WARNING: Skipping Update of $router, outlast is not defined\n"
|
|
Packit |
3f632f |
# unless defined $outlast;
|
|
Packit |
3f632f |
# next;
|
|
Packit |
3f632f |
#}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (defined $inlast and $inlast < 0) {
|
|
Packit |
3f632f |
$inlast += 2**31;
|
|
Packit |
3f632f |
# this is likely to be a broken snmp counter ... lets compensate
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if (defined $outlast and $outlast < 0) {
|
|
Packit |
3f632f |
$outlast += 2**31;
|
|
Packit |
3f632f |
# this is likely to be a broken snmp counter ... lets compensate
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my ($maxin, $maxout, $maxpercent, $avin, $avout, $avpercent,$avmxin, $avmxout,
|
|
Packit |
3f632f |
$cuin, $cuout, $cupercent);
|
|
Packit |
3f632f |
debug('base', "Create Graphics");
|
|
Packit |
3f632f |
if ($rcfg{'options'}{'dorelpercent'}{$router}) {
|
|
Packit |
3f632f |
($maxin, $maxout, $maxpercent, $avin, $avout, $avpercent,
|
|
Packit |
3f632f |
$cuin, $cuout, $cupercent, $avmxin, $avmxout) =
|
|
Packit |
3f632f |
writegraphics($router, \%cfg, \%rcfg, $inlast, $outlast, $time,$LOC, \%opts);
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
($maxin, $maxout ,$avin, $avout, $cuin, $cuout, $avmxin, $avmxout) =
|
|
Packit |
3f632f |
writegraphics($router, \%cfg, \%rcfg, $inlast, $outlast, $time,$LOC, \%opts);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
# skip this update if we did not get anything usefull out of
|
|
Packit |
3f632f |
# writegraphics
|
|
Packit |
3f632f |
next if not defined $maxin;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
debug('base', "Check for Thresholds");
|
|
Packit |
3f632f |
threshcheck(\%cfg,\%rcfg,$cfgfile,$router,$cuin,$cuout);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (defined $opts{'log-only'}){
|
|
Packit |
3f632f |
debug('base', "Disable Graph and HTML generation");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($cfg{logformat} eq 'rateup' and not defined $opts{'log-only'} ){
|
|
Packit |
3f632f |
debug('base', "Check for Write HTML Pages");
|
|
Packit |
3f632f |
writehtml($router, \%cfg, \%rcfg,
|
|
Packit |
3f632f |
$maxin, $maxout, $maxpercent, $avin, $avout, $avmxin, $avmxout, $avpercent,
|
|
Packit |
3f632f |
$cuin, $cuout, $cupercent, $uptime, $name, $LOC)
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
#
|
|
Packit |
3f632f |
clonedirectory($router,\%cfg, \%rcfg);
|
|
Packit |
3f632f |
#
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
#put TZ things back in shape ...
|
|
Packit |
3f632f |
if ($savetz) {
|
|
Packit |
3f632f |
$ENV{'TZ'} = $savetz;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
delete $ENV{'TZ'};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ( $main::OS eq 'UNIX' ){
|
|
Packit |
3f632f |
require 'POSIX.pm';
|
|
Packit |
3f632f |
POSIX::tzset();
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
# Has the cfg file been modified since we started? if so, reload it.
|
|
Packit |
3f632f |
if ( -M $cfgfile < $cfgfile_age and
|
|
Packit |
3f632f |
$cfg{'runasdaemon'} and $cfg{'runasdaemon'} =~ /y/i ) {
|
|
Packit |
3f632f |
# reload the configuration
|
|
Packit |
3f632f |
$cfgfile_age = -M $cfgfile;
|
|
Packit |
3f632f |
debug('base', "Re-reading Config File: $cfgfile");
|
|
Packit |
3f632f |
@routers = (); %cfg = (); %rcfg = ();
|
|
Packit |
3f632f |
readcfg($cfgfile,\@routers,\%cfg,\%rcfg);
|
|
Packit |
3f632f |
cfgcheck(\@routers, \%cfg, \%rcfg, \@target, \%opts);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
debug('base', "End of main Loop");
|
|
Packit |
3f632f |
} while ($cfg{'runasdaemon'} and $cfg{'runasdaemon'} =~ /y/i ); #In daemon mode run forever
|
|
Packit |
3f632f |
debug('base', "Exit main Loop");
|
|
Packit |
3f632f |
# OK we are done, remove the lock files ...
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
debug('base', "Remove Lock Files");
|
|
Packit |
3f632f |
close LOCK; unlink ($templock, $lockfile);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
debug('base', "Store Interface Config Cache");
|
|
Packit |
3f632f |
delete $$confcache{___updated} if exists $$confcache{___updated}; # make sure everything gets written out not only the updated entries
|
|
Packit |
3f632f |
writeconfcache($confcache,$confcachefile);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ( ! $cfg{'runasdaemon'} or $cfg{'runasdaemon'} !~ /y/i ) {
|
|
Packit |
3f632f |
if ( ($EXITCODE & 1) and ($EXITCODE & 2) ) {
|
|
Packit |
3f632f |
# At least one target was sucessful
|
|
Packit |
3f632f |
exit 91;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
elsif ( not ($EXITCODE & 1) and ($EXITCODE & 2) ) {
|
|
Packit |
3f632f |
# All targets failed
|
|
Packit |
3f632f |
exit 92;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# ( $inlast, $outlast, $uptime, $name, $time ) =
|
|
Packit |
3f632f |
# &getcurrent( $target, $rou, $rcfg, $cfg )
|
|
Packit |
3f632f |
# Calculate monitored data for device $rou based on information in @$target
|
|
Packit |
3f632f |
# and referring to configuration data in %$rcfg and %$cfg. In the returned
|
|
Packit |
3f632f |
# list, $inlast and $outlast are the input and output monitored data values,
|
|
Packit |
3f632f |
# $uptime is the device uptime, $name is the device name, and $time is the
|
|
Packit |
3f632f |
# current time when the calculation was performed.
|
|
Packit |
3f632f |
sub getcurrent {
|
|
Packit |
3f632f |
my( $target, $rou, $rcfg, $cfg ) = @_;
|
|
Packit |
3f632f |
# Hash indexed by $mode for conveniently saving $inlast and $outlast
|
|
Packit |
3f632f |
my %last;
|
|
Packit |
3f632f |
# Initialize uptime, device name, and data collection time to empty strings
|
|
Packit |
3f632f |
my $uptime = '';
|
|
Packit |
3f632f |
my $name = '';
|
|
Packit |
3f632f |
my $time = '';
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Calculate input and output monitored data
|
|
Packit |
3f632f |
foreach my $mode( qw( _IN_ _OUT_ ) ) {
|
|
Packit |
3f632f |
# Initialize monitored data, warning message, and death message
|
|
Packit |
3f632f |
# to empty strings
|
|
Packit |
3f632f |
my $data;
|
|
Packit |
3f632f |
my $warning;
|
|
Packit |
3f632f |
my $death;
|
|
Packit |
3f632f |
{
|
|
Packit |
3f632f |
# Code block used to calculate monitoring data
|
|
Packit |
3f632f |
# Localize warning and death exception handlers to capture
|
|
Packit |
3f632f |
# error message less any leading and trailing white space
|
|
Packit |
3f632f |
local $SIG{ __WARN__ } =
|
|
Packit |
3f632f |
sub { $_[0] =~ /^\s*(.+?)\s*$/; $warning = $1; };
|
|
Packit |
3f632f |
local $SIG{ __DIE__ } =
|
|
Packit |
3f632f |
sub { $_[0] =~ /^\s*(.+?)\s*$/; $death = $1; };
|
|
Packit |
3f632f |
# Calculate monitoring data. $rcfg->{ target }{ $rou } contains
|
|
Packit |
3f632f |
# a Perl expression for the calculation.
|
|
Packit |
3f632f |
$data = eval "$rcfg->{target}{$rou}";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
# Test for various exceptions occurring in the calculation
|
|
Packit |
3f632f |
if( $warning ) {
|
|
Packit |
3f632f |
warn "$NOW: ERROR: Target[$rou][$mode] '$$rcfg{target}{$rou}' (warn): $warning\n";
|
|
Packit |
3f632f |
$data = undef;
|
|
Packit |
3f632f |
} elsif( $death ) {
|
|
Packit |
3f632f |
warn "$NOW: ERROR: Target[$rou][$mode] '$$rcfg{target}{$rou}' (kill): $death\n";
|
|
Packit |
3f632f |
$data = undef;
|
|
Packit |
3f632f |
} elsif( $@ ) {
|
|
Packit |
3f632f |
warn "$NOW: ERROR: Target[$rou][$mode] '$$rcfg{target}{$rou}' (eval): $@\n";
|
|
Packit |
3f632f |
$data = undef;
|
|
Packit |
3f632f |
} elsif( not defined $data ) {
|
|
Packit |
3f632f |
warn "$NOW: ERROR: Target[$rou][$mode] '$$rcfg{target}{$rou}' did not eval into defined data\n";
|
|
Packit |
3f632f |
$data = undef;
|
|
Packit |
3f632f |
} elsif( $data and $data !~ /^[-+]?\d+(\.\d*)?([eE][+-]?[0-9]+)?$/ ) {
|
|
Packit |
3f632f |
warn "$NOW: ERROR: Target[$rou][$mode] '$$rcfg{target}{$rou}' evaluated to '$data' instead of a number\n";
|
|
Packit |
3f632f |
$data = undef;
|
|
Packit |
3f632f |
} elsif( length( $data ) > 190 ) {
|
|
Packit |
3f632f |
warn "$NOW: ERROR: $mode value: '$data' is way to long ...\n";
|
|
Packit |
3f632f |
$data = undef;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
# At this point data is considered valid. Round to an integer
|
|
Packit |
3f632f |
# unless RRDTool is in use and this is a gauge
|
|
Packit |
3f632f |
if (not ( $cfg->{ logformat } eq 'rrdtool'
|
|
Packit |
3f632f |
and defined $rcfg->{ options }{ gauge }{ $rou })){
|
|
Packit |
3f632f |
if (ref $data and ref $data eq 'Math::BigFloat') {
|
|
Packit |
3f632f |
$data->ffround( 0 )
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$data = sprintf "%.0f", $data;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
# Remove any leading plus sign
|
|
Packit |
3f632f |
$data =~ s/^\+//;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
$last{ $mode } = $data;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Set $u to the unique index of the @$target array referred to in the
|
|
Packit |
3f632f |
# monitored data calculation for the current device. $u will be set to
|
|
Packit |
3f632f |
# -1 if that index is not unique.
|
|
Packit |
3f632f |
my $u = $rcfg->{ uniqueTarget }{ $rou };
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Get the uptime, device name, and data collection time from the @$target
|
|
Packit |
3f632f |
# array if the monitored data calculation refers only to one target.
|
|
Packit |
3f632f |
# Otherwise it doesn't make sense to do this.
|
|
Packit |
3f632f |
if( $u >= 0 ) {
|
|
Packit |
3f632f |
$uptime = $target->[ $u ]{ _UPTIME_ };
|
|
Packit |
3f632f |
$name = $target->[ $u ]{ _NAME_ };
|
|
Packit |
3f632f |
$time = $target->[ $u ]{ _TIME_ };
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($time =~ /^([-0-9.]+)$/) {
|
|
Packit |
3f632f |
$time = $1;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Set the time to the current time if it was not set above
|
|
Packit |
3f632f |
$time = time unless $time;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Cache uptime location for reading name
|
|
Packit |
3f632f |
my( $uploc );
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Get the uptime and device name from the alternate location (community@host or
|
|
Packit |
3f632f |
# (OID:community@host or OID) that may have been specified with the RouterUptime
|
|
Packit |
3f632f |
# target keyword
|
|
Packit |
3f632f |
if( defined $rcfg->{ routeruptime }{ $rou } ) {
|
|
Packit |
3f632f |
my( $noid, $nloc ) = split( /:/, $rcfg->{ routeruptime }{ $rou }, 2 );
|
|
Packit |
3f632f |
# If only location (community@host) was specified then
|
|
Packit |
3f632f |
# move the location details into the right place
|
|
Packit |
3f632f |
if( $noid =~ /@/ ) {
|
|
Packit |
3f632f |
$nloc = $noid;
|
|
Packit |
3f632f |
$noid = undef;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
# If no OID (community@host) was specified use the hardcoded default
|
|
Packit |
3f632f |
if( not $noid ) {
|
|
Packit |
3f632f |
$noid = 'sysUptime';
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
# If no location (community@host) was specified use values from the
|
|
Packit |
3f632f |
# unique target referred to in the monitored data calculation
|
|
Packit |
3f632f |
if( not $nloc ){
|
|
Packit |
3f632f |
if ($u >= 0) {
|
|
Packit |
3f632f |
my $comm = $target->[ $u ]{ Community };
|
|
Packit |
3f632f |
my $host = $target->[ $u ]{ Host };
|
|
Packit |
3f632f |
my $opt = $target->[ $u ]{ SnmpOpt };
|
|
Packit |
3f632f |
$nloc = "$comm\@$host$opt";
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
die "$NOW: ERROR: You must specify the location part of the RouterUptime oid for non unique targets! ($rou)\n";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$uploc = $nloc;
|
|
Packit |
3f632f |
# Get the device uptime if $noid(OID) and $nloc (community@host) have been specified
|
|
Packit |
3f632f |
# one way or the other
|
|
Packit |
3f632f |
debug('base', "Fetching sysUptime and sysName from: $noid:$nloc");
|
|
Packit |
3f632f |
( $uptime, $name ) = snmpget( $uploc, $rcfg->{ snmpoptions }{ $rou }, $noid, 'sysName');
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Get the device name from the alternate location (OID or
|
|
Packit |
3f632f |
# OID:community@host) that may have been specified with the RouterName
|
|
Packit |
3f632f |
# target keyword
|
|
Packit |
3f632f |
if( defined $rcfg->{ routername }{ $rou } ) {
|
|
Packit |
3f632f |
my( $noid, $nloc ) = split( /:/, $rcfg->{ routername }{ $rou }, 2 );
|
|
Packit |
3f632f |
# If no location (community@host) was specified use values from the
|
|
Packit |
3f632f |
# unique target referred to in the monitored data calculation
|
|
Packit |
3f632f |
if( $u >= 0 and not $nloc ) {
|
|
Packit |
3f632f |
my $comm = $target->[ $u ]{ Community };
|
|
Packit |
3f632f |
my $host = $target->[ $u ]{ Host };
|
|
Packit |
3f632f |
my $opt = $target->[ $u ]{ SnmpOpt };
|
|
Packit |
3f632f |
$nloc = "$comm\@$host$opt";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
# Get the location from the RouterUptime keyword if that is defined
|
|
Packit |
3f632f |
# and $nloc has not otherwise been specified
|
|
Packit |
3f632f |
$nloc = $uploc if $uploc and not $nloc;
|
|
Packit |
3f632f |
# Get the device name if $nloc (community@host) has been specified
|
|
Packit |
3f632f |
# one way or the other
|
|
Packit |
3f632f |
debug('base', "Fetching sysName from: $noid:$nloc");
|
|
Packit |
3f632f |
( $name ) = snmpget( $nloc, $$rcfg{snmpoptions}{ $rou }, $noid ) if $nloc;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
return ( $last{ _IN_ }, $last{ _OUT_ }, $uptime, $name, $time );
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
sub rateupcheck ($) {
|
|
Packit |
3f632f |
my $router = shift;
|
|
Packit |
3f632f |
if ($?) {
|
|
Packit |
3f632f |
my $value = $?;
|
|
Packit |
3f632f |
my $signal = $? & 127; #ignore the most significant bit
|
|
Packit |
3f632f |
#as it is always one when it is a returning
|
|
Packit |
3f632f |
#child says dave ...
|
|
Packit |
3f632f |
if (($MRTG_lib::OS ne 'UNIX') || ($signal != 127)) {
|
|
Packit |
3f632f |
my $exitval = $? >> 8;
|
|
Packit |
3f632f |
warn "$NOW: WARNING: rateup died from Signal $signal\n".
|
|
Packit |
3f632f |
" with Exit Value $exitval when doing router '$router'\n".
|
|
Packit |
3f632f |
" Signal was $signal, Returncode was $exitval\n"
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
sub clonedirectory {
|
|
Packit |
3f632f |
my($router,$cfg, $rcfg) = @_;
|
|
Packit |
3f632f |
require File::Copy;
|
|
Packit |
3f632f |
import File::Copy;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
return unless ( $$rcfg{'clonedirectory'}{$router} );
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my ($clonedstdir, $clonedsttarget ,$srcname, $dstname);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
($clonedstdir, $clonedsttarget ) = split (/,|\s+/, $$rcfg{'clonedirectory'}{$router}) if ( $$rcfg{'clonedirectory'}{$router} =~ /,|\S\s+\S/ );
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ( defined $clonedsttarget ) {
|
|
Packit |
3f632f |
$clonedsttarget =~ s/\s+//;
|
|
Packit |
3f632f |
$clonedsttarget = lc($clonedsttarget);
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$clonedstdir = $$rcfg{'clonedirectory'}{$router};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ( $$rcfg{'directory'}{$router} ne $clonedstdir) {
|
|
Packit |
3f632f |
$clonedstdir =~ s/\s+$//;
|
|
Packit |
3f632f |
$clonedstdir .= "/" unless ($clonedstdir =~ /\/$/);
|
|
Packit |
3f632f |
my $fullpathsrcdir = "$$cfg{'logdir'}$$rcfg{'directory'}{$router}";
|
|
Packit |
3f632f |
my $fullpathdstdir = "$$cfg{'logdir'}$clonedstdir";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
die "$NOW: ERROR: Destination dir: $fullpathdstdir not found for cloning process\n" unless ( -e $fullpathdstdir );
|
|
Packit |
3f632f |
die "$NOW: ERROR: Destination dir: $fullpathdstdir is not a directory destination for cloning process\n" unless ( -d $fullpathdstdir );
|
|
Packit |
3f632f |
die "$NOW: ERROR: Destination dir: $fullpathdstdir is not writeable for cloning process\n" unless ( -w $fullpathdstdir );
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ( defined $clonedsttarget ) {
|
|
Packit |
3f632f |
debug('base', "Clone directory $fullpathsrcdir to $fullpathdstdir " .
|
|
Packit |
3f632f |
"renaming target $router to $clonedsttarget");
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
debug('base', "Clone directory $fullpathsrcdir to $fullpathdstdir");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
foreach my $srcfile (<$fullpathsrcdir$router\[.-\]*>) {
|
|
Packit |
3f632f |
debug('base', "copying $srcfile $fullpathdstdir");
|
|
Packit |
3f632f |
copy("$srcfile","$fullpathdstdir") or warn "$NOW: WARNING: Cloning $srcfile to $fullpathdstdir unsuccessful; $!\n";
|
|
Packit |
3f632f |
if ($srcfile =~ /\.html/i) {
|
|
Packit |
3f632f |
debug('base', "altering $fullpathdstdir/$router.$$rcfg{'extension'}{$router}");
|
|
Packit |
3f632f |
#
|
|
Packit |
3f632f |
my $dirrel = "../" x ($$rcfg{'clonedirectory'}{$router} =~ tr|/|/|);
|
|
Packit |
3f632f |
#
|
|
Packit |
3f632f |
debug('base', "dirrel $dirrel $clonedstdir");
|
|
Packit |
3f632f |
open(HTML,"$fullpathdstdir/$router.$$rcfg{'extension'}{$router}");
|
|
Packit |
3f632f |
my @CLONEHTML = <HTML>;
|
|
Packit |
3f632f |
close(HTML);
|
|
Packit |
3f632f |
foreach ( @CLONEHTML ) {
|
|
Packit |
3f632f |
if ( defined $clonedsttarget and /$router/ ) {
|
|
Packit |
3f632f |
debug('base', "altering $router to $clonedsttarget in html file");
|
|
Packit |
3f632f |
s/$router/$clonedsttarget/i;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ( /SRC=/i and /$$rcfg{'directory'}{$router}/ ) {
|
|
Packit |
3f632f |
debug('base', "altering from $_");
|
|
Packit |
3f632f |
s|(\.\./)+|$dirrel|;
|
|
Packit |
3f632f |
s|$$rcfg{'directory'}{$router}|$clonedstdir|;
|
|
Packit |
3f632f |
debug('base', "altering to $_");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
open(HTML,">$fullpathdstdir/$router.$$rcfg{'extension'}{$router}");
|
|
Packit |
3f632f |
print HTML $_ for ( @CLONEHTML );
|
|
Packit |
3f632f |
close(HTML);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ( defined $clonedsttarget ) {
|
|
Packit |
3f632f |
$srcfile =~ /.+\/(.+)?$/;
|
|
Packit |
3f632f |
$srcname = $1;
|
|
Packit |
3f632f |
$dstname = $srcname;
|
|
Packit |
3f632f |
$dstname =~ s/$router/$clonedsttarget/;
|
|
Packit |
3f632f |
debug('base', "Clone renaming $srcname to $dstname at $fullpathdstdir");
|
|
Packit |
3f632f |
rename("$fullpathdstdir/$srcname","$fullpathdstdir/$dstname") or
|
|
Packit |
3f632f |
warn "$NOW: WARNING: Renaming $fullpathdstdir/$srcname to $fullpathdstdir/$dstname unsuccessful; $!\n";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: Cloning to the same place suspended. ; $!\n";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
sub writegraphics {
|
|
Packit |
3f632f |
my($router, $cfg, $rcfg, $inlast, $outlast, $time,$LOC, $opts) = @_;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my($absmax,$maxv, $maxvi, $maxvo, $i, $period, $res);
|
|
Packit |
3f632f |
my(@exec, @mxvls, @metas);
|
|
Packit |
3f632f |
my(%maxin, %maxout, %maxpercent, %avin, %avout, %avmxin, %avmxout, %avpercent, %cuin, %cuout, %cupercent);
|
|
Packit |
3f632f |
my($rrdinfo);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
@metas = ();
|
|
Packit |
3f632f |
$maxvi = $$rcfg{'maxbytes1'}{$router};
|
|
Packit |
3f632f |
$maxvo = $$rcfg{'maxbytes2'}{$router};
|
|
Packit |
3f632f |
if ($maxvi > $maxvo) {
|
|
Packit |
3f632f |
$maxv = $maxvi;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$maxv = $maxvo;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
$absmax = $$rcfg{'absmax'}{$router};
|
|
Packit |
3f632f |
$absmax = $maxv unless defined $absmax;
|
|
Packit |
3f632f |
if ($absmax < $maxv) {
|
|
Packit |
3f632f |
die "$NOW: ERROR: AbsMax: $absmax is smaller than MaxBytes: $maxv\n";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# select whether the datasource gives relative or absolute return values.
|
|
Packit |
3f632f |
my $up_abs="u";
|
|
Packit |
3f632f |
$up_abs='m' if defined $$rcfg{'options'}{'perminute'}{$router};
|
|
Packit |
3f632f |
$up_abs='h' if defined $$rcfg{'options'}{'perhour'}{$router};
|
|
Packit |
3f632f |
$up_abs='d' if defined $$rcfg{'options'}{'derive'}{$router};
|
|
Packit |
3f632f |
$up_abs='a' if defined $$rcfg{'options'}{'absolute'}{$router};
|
|
Packit |
3f632f |
$up_abs='g' if defined $$rcfg{'options'}{'gauge'}{$router};
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $dotrrd = "$$cfg{'logdir'}$$rcfg{'directory'}{$router}$router.rrd";
|
|
Packit |
3f632f |
my $dotlog = "$$cfg{'logdir'}$$rcfg{'directory'}{$router}$router.log";
|
|
Packit |
3f632f |
my $reallog = $$cfg{logformat} eq 'rrdtool' ? $dotrrd : $dotlog;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (defined $$cfg{maxage} and -e $reallog and time()-$$cfg{maxage} > (stat($reallog))[9]){
|
|
Packit |
3f632f |
warn "$NOW: ERROR: skipping update of $router. As $reallog is older than MaxAge ($$cfg{maxage} s)\n";
|
|
Packit |
3f632f |
return undef;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($$cfg{logformat} eq 'rrdtool') {
|
|
Packit |
3f632f |
debug('base',"start RRDtool section");
|
|
Packit |
3f632f |
# make sure we got some sane default here
|
|
Packit |
3f632f |
my %dstype = qw/u COUNTER a ABSOLUTE g GAUGE h COUNTER m COUNTER d DERIVE/;
|
|
Packit |
3f632f |
$up_abs = $dstype{$up_abs};
|
|
Packit |
3f632f |
# update the database.
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# set minimum/maximum values. use 'U' if we cannot get good values
|
|
Packit |
3f632f |
# the lower bound is hardcoded to 0
|
|
Packit |
3f632f |
my $absi = $maxvi;
|
|
Packit |
3f632f |
my $abso = $maxvo;
|
|
Packit |
3f632f |
$absi = $abso = $$rcfg{'absmax'}{$router}
|
|
Packit |
3f632f |
if defined $$rcfg{'absmax'}{$router};
|
|
Packit |
3f632f |
debug('base',"maxi:$absi, maxo:$abso");
|
|
Packit |
3f632f |
$absi = 'U' if $absi == 0;
|
|
Packit |
3f632f |
$abso = 'U' if $abso == 0;
|
|
Packit |
3f632f |
# check to see if we already have an RRD file or have to create it
|
|
Packit |
3f632f |
# maybe we can convert an .log file to the new rrd format
|
|
Packit |
3f632f |
if( $RRDs::VERSION >= 1.4 and $$cfg{rrdcached} and $$cfg{rrdcached} !~ /^unix:/ ) {
|
|
Packit |
3f632f |
# rrdcached in network mode. No log conversion possible.
|
|
Packit |
3f632f |
# In this mode, we cannot use absolute paths. So, we strip logdir from the name.
|
|
Packit |
3f632f |
$dotrrd = "$$rcfg{'directory'}{$router}$router.rrd";
|
|
Packit |
3f632f |
if( $RRDs::VERSION < 1.49 ) {
|
|
Packit |
3f632f |
# This version of RRD doesnt support info, create and tune
|
|
Packit |
3f632f |
debug('base',"Unable to verify RRD file with this version of rrdcached");
|
|
Packit |
3f632f |
if( !$main::verified_rrd{$dotrrd} ) {
|
|
Packit |
3f632f |
warn "WARN: Unable to verify $dotrrd with this version of RRDTool\n";
|
|
Packit |
3f632f |
$main::verified_rrd{$dotrrd} = 1;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} elsif( !$main::verified_rrd{$dotrrd} ) {
|
|
Packit |
3f632f |
# Test to see if it exists
|
|
Packit |
3f632f |
debug('base',"Attempting to verify RRD file via rrdcached");
|
|
Packit |
3f632f |
$rrdinfo = RRDs::info($dotrrd,'--daemon',$$cfg{rrdcached},'--noflush');
|
|
Packit |
3f632f |
if(!$rrdinfo) { # doesnt exist, or cannot be accessed
|
|
Packit |
3f632f |
my $e = RRDs::error();
|
|
Packit |
3f632f |
warn "$NOW: Cannot access $dotrrd; will attempt to (re)create it: $e\n" if $e;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# don't fail if interval is not set
|
|
Packit |
3f632f |
my $interval = $$cfg{interval};
|
|
Packit |
3f632f |
my $minhb = int($$cfg{interval} * 60)*2;
|
|
Packit |
3f632f |
$minhb = 600 if ($minhb <600);
|
|
Packit |
3f632f |
my $rows = $$rcfg{'rrdrowcount'}{$router} || int( 4000 / $interval);
|
|
Packit |
3f632f |
my $rows30m = $$rcfg{'rrdrowcount30m'}{$router} || 800;
|
|
Packit |
3f632f |
my $rows2h = $$rcfg{'rrdrowcount2h'}{$router} || 800;
|
|
Packit |
3f632f |
my $rows1d = $$rcfg{'rrdrowcount1d'}{$router} || 800;
|
|
Packit |
3f632f |
my @args = ($dotrrd, '-b', $time-10, '-s', int($interval * 60),
|
|
Packit |
3f632f |
"DS:ds0:$up_abs:$minhb:0:$absi",
|
|
Packit |
3f632f |
"DS:ds1:$up_abs:$minhb:0:$abso",
|
|
Packit |
3f632f |
"RRA:AVERAGE:0.5:1:$rows",
|
|
Packit |
3f632f |
( $interval < 30 ? ("RRA:AVERAGE:0.5:".int(30/$interval).":".$rows30m):()),
|
|
Packit |
3f632f |
"RRA:AVERAGE:0.5:".int(120/$interval).":".$rows2h,
|
|
Packit |
3f632f |
"RRA:AVERAGE:0.5:".int(1440/$interval).":".$rows1d,
|
|
Packit |
3f632f |
"RRA:MAX:0.5:1:$rows",
|
|
Packit |
3f632f |
( $interval < 30 ? ("RRA:MAX:0.5:".int(30/$interval).":".$rows30m):()),
|
|
Packit |
3f632f |
"RRA:MAX:0.5:".int(120/$interval).":".$rows2h,
|
|
Packit |
3f632f |
"RRA:MAX:0.5:".int(1440/$interval).":".$rows1d);
|
|
Packit |
3f632f |
# do we have holt winters rras defined here ?
|
|
Packit |
3f632f |
if (defined $$rcfg{'rrdhwrras'} and defined $$rcfg{'rrdhwrras'}{$router}){
|
|
Packit |
3f632f |
push @args, split(/\s+/, $$rcfg{'rrdhwrras'}{$router});
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
push @args,"--daemon", $$cfg{rrdcached};
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
debug('base',"create $dotrrd via rrdcached");
|
|
Packit |
3f632f |
debug('log', "RRDs::create(".join(',',@args).")");
|
|
Packit |
3f632f |
RRDs::create(@args);
|
|
Packit |
3f632f |
$e = RRDs::error();
|
|
Packit |
3f632f |
die "$NOW: ERROR: Cannot create RRD ".join(',',@args)."- $e\n" if $e;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
# Does the RRD file need to be tuned?
|
|
Packit |
3f632f |
if(
|
|
Packit |
3f632f |
($rrdinfo->{"ds[ds0].max"} != $absi)
|
|
Packit |
3f632f |
||($rrdinfo->{"ds[ds1].max"} != $abso)
|
|
Packit |
3f632f |
||($rrdinfo->{"ds[ds0].type"} ne $up_abs)
|
|
Packit |
3f632f |
||($rrdinfo->{"ds[ds1].type"} ne $up_abs)
|
|
Packit |
3f632f |
) {
|
|
Packit |
3f632f |
debug('base',"RRD file needs to be tuned");
|
|
Packit |
3f632f |
warn "$NOW: RRDFile $dotrrd needs to be tuned but cannot do this remotely.\n";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
$main::verified_rrd{$dotrrd} = 1;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
debug('base',"No need to verify this file again");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} elsif (-e $dotlog and not -e $dotrrd) {
|
|
Packit |
3f632f |
debug('base',"converting $dotlog to RRD format");
|
|
Packit |
3f632f |
if(defined $RRDs::VERSION and $RRDs::VERSION < 1.000271){
|
|
Packit |
3f632f |
die "$NOW: ERROR: RRDtool version 1.0.27 or later required to perform log2rrd conversion\n";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
log2rrd($router,$cfg,$rcfg);
|
|
Packit |
3f632f |
} elsif (! -e $dotrrd) {
|
|
Packit |
3f632f |
#nope it seems we have to create a new one
|
|
Packit |
3f632f |
debug('base',"create $dotrrd");
|
|
Packit |
3f632f |
# create the rrd if it doesn't exist
|
|
Packit |
3f632f |
# don't fail if interval is not set
|
|
Packit |
3f632f |
my $interval = $$cfg{interval};
|
|
Packit |
3f632f |
my $minhb = int($$cfg{interval} * 60)*2;
|
|
Packit |
3f632f |
$minhb = 600 if ($minhb <600);
|
|
Packit |
3f632f |
my $rows = $$rcfg{'rrdrowcount'}{$router} || int( 4000 / $interval);
|
|
Packit |
3f632f |
my $rows30m = $$rcfg{'rrdrowcount30m'}{$router} || 800;
|
|
Packit |
3f632f |
my $rows2h = $$rcfg{'rrdrowcount2h'}{$router} || 800;
|
|
Packit |
3f632f |
my $rows1d = $$rcfg{'rrdrowcount1d'}{$router} || 800;
|
|
Packit |
3f632f |
my @args = ($dotrrd, '-b', $time-10, '-s', int($interval * 60),
|
|
Packit |
3f632f |
"DS:ds0:$up_abs:$minhb:0:$absi",
|
|
Packit |
3f632f |
"DS:ds1:$up_abs:$minhb:0:$abso",
|
|
Packit |
3f632f |
"RRA:AVERAGE:0.5:1:$rows",
|
|
Packit |
3f632f |
( $interval < 30 ? ("RRA:AVERAGE:0.5:".int(30/$interval).":".$rows30m):()),
|
|
Packit |
3f632f |
"RRA:AVERAGE:0.5:".int(120/$interval).":".$rows2h,
|
|
Packit |
3f632f |
"RRA:AVERAGE:0.5:".int(1440/$interval).":".$rows1d,
|
|
Packit |
3f632f |
"RRA:MAX:0.5:1:$rows",
|
|
Packit |
3f632f |
( $interval < 30 ? ("RRA:MAX:0.5:".int(30/$interval).":".$rows30m):()),
|
|
Packit |
3f632f |
"RRA:MAX:0.5:".int(120/$interval).":".$rows2h,
|
|
Packit |
3f632f |
"RRA:MAX:0.5:".int(1440/$interval).":".$rows1d);
|
|
Packit |
3f632f |
# do we have holt winters rras defined here ?
|
|
Packit |
3f632f |
if (defined $$rcfg{'rrdhwrras'} and defined $$rcfg{'rrdhwrras'}{$router}){
|
|
Packit |
3f632f |
push @args, split(/\s+/, $$rcfg{'rrdhwrras'}{$router});
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
debug('log', "RRDs::create(".join(',',@args).")");
|
|
Packit |
3f632f |
RRDs::create(@args);
|
|
Packit |
3f632f |
my $e = RRDs::error();
|
|
Packit |
3f632f |
die "$NOW: ERROR: Cannot create RRD ".join(',',@args)."- $e\n" if $e;
|
|
Packit |
3f632f |
} elsif ( -M $dotrrd > 0 ) {
|
|
Packit |
3f632f |
# update the minimum/maximum according to maxbytes/absmax
|
|
Packit |
3f632f |
# and (re)set the data-source-type to reflect cfg changes
|
|
Packit |
3f632f |
# cost: 1 read/write cycle, but update will reuse the buffered data
|
|
Packit |
3f632f |
# in daemon mode this will only happen in the first round
|
|
Packit |
3f632f |
my @args = ($dotrrd, '-a', "ds0:$absi", '-a', "ds1:$abso",
|
|
Packit |
3f632f |
'-d', "ds0:$up_abs", '-d', "ds1:$up_abs");
|
|
Packit |
3f632f |
debug('log', "RRDs::tune(@args)");
|
|
Packit |
3f632f |
my $start = gettimeofday();
|
|
Packit |
3f632f |
RRDs::tune(@args);
|
|
Packit |
3f632f |
debug('prof',sprintf("RRDs::tune $dotrrd - %.3fs",gettimeofday()-$start));
|
|
Packit |
3f632f |
my $e = RRDs::error();
|
|
Packit |
3f632f |
warn "$NOW: ERROR: Cannot tune logfile: $e\n" if $e;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
# update the rrd
|
|
Packit |
3f632f |
$inlast = 'U' unless defined $inlast and $inlast =~ /\S/ and $inlast ne '##UNDEF##';
|
|
Packit |
3f632f |
$outlast = 'U' unless defined $outlast and $outlast =~ /\S/ and $outlast ne '##UNDEF##';
|
|
Packit |
3f632f |
debug('log', "RRDs::update($dotrrd, '$time:$inlast:$outlast')");
|
|
Packit |
3f632f |
my $start = gettimeofday();
|
|
Packit |
3f632f |
my $rrddata = 0;
|
|
Packit |
3f632f |
if ( $RRDs::VERSION >= 1.4 and $$cfg{rrdcached} ){
|
|
Packit |
3f632f |
RRDs::update($dotrrd, '--daemon', $$cfg{rrdcached}, "$time:$inlast:$outlast");
|
|
Packit |
3f632f |
debug('prof',sprintf("RRDs::update $dotrrd (rrdcached) - %.3fs",gettimeofday()-$start));
|
|
Packit |
3f632f |
$rrddata = \{ dummy => "" };
|
|
Packit |
3f632f |
} elsif ( $RRDs::VERSION >= 1.2 ){
|
|
Packit |
3f632f |
$rrddata=RRDs::updatev($dotrrd, "$time:$inlast:$outlast");
|
|
Packit |
3f632f |
debug('prof',sprintf("RRDs::updatev $dotrrd - %.3fs",gettimeofday()-$start));
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
RRDs::update($dotrrd, "$time:$inlast:$outlast");
|
|
Packit |
3f632f |
debug('prof',sprintf("RRDs::update $dotrrd - %.3fs",gettimeofday()-$start));
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
my $e = RRDs::error();
|
|
Packit |
3f632f |
warn "$NOW: ERROR: Cannot update $dotrrd with '$time:$inlast:$outlast' $e\n" if ($e);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Send a copy of the time series data to graphite
|
|
Packit |
3f632f |
if(defined $$cfg{sendtographite}) {
|
|
Packit |
3f632f |
my @a = split ",",$$cfg{sendtographite};
|
|
Packit |
3f632f |
if (not $graphiteObj) {
|
|
Packit |
3f632f |
$graphiteObj = Net::Graphite->new(
|
|
Packit |
3f632f |
host => $a[0],
|
|
Packit |
3f632f |
port => $a[1],
|
|
Packit |
3f632f |
trace => 0,
|
|
Packit |
3f632f |
proto => "tcp",
|
|
Packit |
3f632f |
timeout => 1,
|
|
Packit |
3f632f |
fire_and_forget => 1,
|
|
Packit |
3f632f |
return_connect_error => 0
|
|
Packit |
3f632f |
);
|
|
Packit |
3f632f |
if($graphiteObj->connect) {
|
|
Packit |
3f632f |
debug('log',"successfully opened graphite socket ($graphiteObj)\n");
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
debug('log',"graphite connect error: $!\n");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# make a copy of the router name for use in the graphite namespace
|
|
Packit |
3f632f |
my $graphiterouter = $router;
|
|
Packit |
3f632f |
# periods are delimiters in the graphite namespace so change them to underscores
|
|
Packit |
3f632f |
$graphiterouter =~ s/_/\./g;
|
|
Packit |
3f632f |
# commas are not allowed
|
|
Packit |
3f632f |
$graphiterouter =~ s/,//g; #remove commas
|
|
Packit |
3f632f |
#set up MRTG's 'in' var naming for graphite
|
|
Packit |
3f632f |
my $graphitein;
|
|
Packit |
3f632f |
if ($$rcfg{'legendi'}{$router}) {
|
|
Packit |
3f632f |
$graphitein = $$rcfg{'legendi'}{$router};
|
|
Packit |
3f632f |
# if the 'in' var contains an underscore, change to a period so graphite will delimit on it
|
|
Packit |
3f632f |
$graphitein =~ s/_/\./g;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
# if legendi is not specified, just use 'in'
|
|
Packit |
3f632f |
$graphitein = "in";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
#set up MRTG's 'out' var naming for graphite
|
|
Packit |
3f632f |
my $graphiteout;
|
|
Packit |
3f632f |
if ($$rcfg{'legendo'}{$router}) {
|
|
Packit |
3f632f |
$graphiteout = $$rcfg{'legendo'}{$router};
|
|
Packit |
3f632f |
# if the 'out' var contains an underscore, change to a period so graphite will delimit on it
|
|
Packit |
3f632f |
$graphiteout =~ s/_/\./g;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
# if legendo is not specified, just use 'out'
|
|
Packit |
3f632f |
$graphiteout = "out";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $graphitensprefix="m2g";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# verify that the 'in' value is numeric (ints, floats, +, -) , and send to graphite
|
|
Packit |
3f632f |
if($inlast =~ /^[+-]?([0-9]*[.])?[0-9]+$/) {
|
|
Packit |
3f632f |
# send the 'in' var data to graphite, and log it appropriately
|
|
Packit |
3f632f |
debug('log', "graphite->send($graphitensprefix.$graphiterouter.$graphitein,$inlast,$time)\n");
|
|
Packit |
3f632f |
$graphiteObj->send(
|
|
Packit |
3f632f |
path => "$graphitensprefix.$graphiterouter.$graphitein",
|
|
Packit |
3f632f |
value => "$inlast",
|
|
Packit |
3f632f |
time => $time,
|
|
Packit |
3f632f |
);
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
debug('log', "WARNING - skipped graphite->send($graphitensprefix.$graphiterouter.$graphitein,$inlast,$time) because value ($inlast) is non-numeric\n");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# verify that the 'out' value is numeric (ints, floats, +, -) , and send to graphite
|
|
Packit |
3f632f |
if($outlast =~ /^[+-]?([0-9]*[.])?[0-9]+$/) {
|
|
Packit |
3f632f |
# send the 'out' var data to graphite, and log it appropriately
|
|
Packit |
3f632f |
debug('log', "graphite->send($graphitensprefix.$graphiterouter.$graphiteout,$outlast,$time)\n");
|
|
Packit |
3f632f |
$graphiteObj->send(
|
|
Packit |
3f632f |
path => "$graphitensprefix.$graphiterouter.$graphiteout",
|
|
Packit |
3f632f |
value => "$outlast",
|
|
Packit |
3f632f |
time => $time,
|
|
Packit |
3f632f |
);
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
debug('log', "WARNING - skipped graphite->send($graphitensprefix.$graphiterouter.$graphiteout,$outlast,$time) because value ($outlast) is non-numeric\n");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
# done sending to graphite for this iteration
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ( $RRDs::VERSION < 1.2 ){
|
|
Packit |
3f632f |
# get the rrdtool-processed values back from rrdtool
|
|
Packit |
3f632f |
# for the threshold checks (we cannot use the fetched data)
|
|
Packit |
3f632f |
$start = gettimeofday();
|
|
Packit |
3f632f |
my $info = RRDs::info($dotrrd);
|
|
Packit |
3f632f |
debug('prof',sprintf("RRDs::info $dotrrd - %.3fs",gettimeofday()-$start));
|
|
Packit |
3f632f |
my $lasttime = $info->{last_update} - $info->{last_update} % $info->{step};
|
|
Packit |
3f632f |
debug('log', "RRDs::info($dotrrd)");
|
|
Packit |
3f632f |
$e = RRDs::error();
|
|
Packit |
3f632f |
warn "$NOW: ERROR: Cannot 'info' $dotrrd: $e\n" if ($e);
|
|
Packit |
3f632f |
$start = gettimeofday();
|
|
Packit |
3f632f |
my $fetch = (RRDs::fetch($dotrrd,'AVERAGE','-s',$lasttime-1,'-e',$lasttime))[3];
|
|
Packit |
3f632f |
debug('prof',sprintf("RRDs::fetch $dotrrd - %.3fs",gettimeofday()-$start));
|
|
Packit |
3f632f |
$e = RRDs::error();
|
|
Packit |
3f632f |
warn "$NOW: ERROR: Cannot 'fetch' $dotrrd: $e\n" if ($e);
|
|
Packit |
3f632f |
debug('log', "RRDs::fetch($dotrrd,'AVERAGE','-s',$lasttime,'-e',$lasttime)");
|
|
Packit |
3f632f |
$cuin{d}{$router} = $fetch->[0][0];
|
|
Packit |
3f632f |
$cuout{d}{$router} = $fetch->[0][1];
|
|
Packit |
3f632f |
} elsif ( $RRDs::VERSION >= 1.4 and $$cfg{rrdcached} ){
|
|
Packit |
3f632f |
# Cannot check thresholds
|
|
Packit |
3f632f |
} elsif($rrddata) {
|
|
Packit |
3f632f |
my $utime = $time - ($time % int($cfg->{interval}*60));
|
|
Packit |
3f632f |
$cuin{d}{$router} = $rrddata->{"[$utime]RRA[AVERAGE][1]DS[ds0]"};
|
|
Packit |
3f632f |
$cuout{d}{$router} = $rrddata->{"[$utime]RRA[AVERAGE][1]DS[ds1]"};
|
|
Packit |
3f632f |
$cuin{d_hwfail}{$router} = $rrddata->{"[$utime]RRA[FAILURES][1]DS[ds0]"};
|
|
Packit |
3f632f |
$cuout{d_hwfail}{$router} = $rrddata->{"[$utime]RRA[FAILURES][1]DS[ds1]"};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
my $in = defined $cuin{d}{$router} ? $cuin{d}{$router} : "???" ;
|
|
Packit |
3f632f |
my $out = defined $cuout{d}{$router} ? $cuout{d}{$router} : "???" ;
|
|
Packit |
3f632f |
debug('log', " got: $in/$out");
|
|
Packit |
3f632f |
# the html pages and the graphics are created at "call time" so that's it!
|
|
Packit |
3f632f |
# (the returned hashes are empty, it's just to minimize the changes to mrtg)
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
|
|
Packit |
3f632f |
return (\%maxin, \%maxout, \%maxpercent, \%avin, \%avout, \%avpercent, \%cuin, \%cuout, \%cupercent, \%avmxin, \%avmxout);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
return (\%maxin, \%maxout, \%avin, \%avout, \%cuin, \%cuout, \%avmxin, \%avmxout );
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
########## rrdtool users have left here ###############
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
((($MRTG_lib::OS eq 'NT' or $MRTG_lib::OS eq 'OS2') and (-e "${FindBin::Bin}${MRTG_lib::SL}rateup.exe")) or
|
|
Packit |
3f632f |
(($MRTG_lib::OS eq 'NW') and (-e "SYS:/Mrtg/bin/rateup.nlm")) or
|
|
Packit |
3f632f |
(-x "${FindBin::Bin}${MRTG_lib::SL}rateup")) or
|
|
Packit |
3f632f |
die "$NOW: ERROR: Can't Execute '${FindBin::Bin}${MRTG_lib::SL}rateup'\n";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# rateup does not know about undef so we make inlast and outlast ready for rateup
|
|
Packit |
3f632f |
#warn "$NOW: ERROR: inlast is undefined. Skipping $router\n" unless defined $inlast;
|
|
Packit |
3f632f |
#warn "$NOW: ERROR: outlast is undefined. Skipping $router\n" unless defined $outlast;
|
|
Packit |
3f632f |
#return undef unless defined $inlast and defined $outlast;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# set values to -1 to tell rateup about unknown values
|
|
Packit |
3f632f |
$inlast = -1 unless defined $inlast;
|
|
Packit |
3f632f |
$outlast = -1 unless defined $outlast;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# untaint in and out
|
|
Packit |
3f632f |
if ($inlast =~ /^([-0-9.]+)$/) {
|
|
Packit |
3f632f |
$inlast = $1;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ($outlast =~ /^([-0-9.]+)$/) {
|
|
Packit |
3f632f |
$outlast = $1;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
|
|
Packit |
3f632f |
@exec = ("${FindBin::Bin}${MRTG_lib::SL}rateup",
|
|
Packit |
3f632f |
"$$cfg{'logdir'}$$rcfg{'directory'}{$router}","$router",
|
|
Packit |
3f632f |
$time, $$rcfg{'options'}{'unknaszero'}{$router} ? '-z':'-Z',
|
|
Packit |
3f632f |
"$up_abs"."p", $inlast, $outlast, $absmax,
|
|
Packit |
3f632f |
"C", $$rcfg{'rgb1'}{$router},$$rcfg{'rgb2'}{$router},
|
|
Packit |
3f632f |
$$rcfg{'rgb3'}{$router},$$rcfg{'rgb4'}{$router},
|
|
Packit |
3f632f |
$$rcfg{'rgb5'}{$router});
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
@exec = ("${FindBin::Bin}${MRTG_lib::SL}rateup",
|
|
Packit |
3f632f |
"$$cfg{'logdir'}$$rcfg{'directory'}{$router}","$router",
|
|
Packit |
3f632f |
$time, $$rcfg{'options'}{'unknaszero'}{$router} ? '-z':'-Z',
|
|
Packit |
3f632f |
"$up_abs", $inlast, $outlast, $absmax,
|
|
Packit |
3f632f |
"c", $$rcfg{'rgb1'}{$router},$$rcfg{'rgb2'}{$router},
|
|
Packit |
3f632f |
$$rcfg{'rgb3'}{$router},$$rcfg{'rgb4'}{$router});
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# If this list grows anymore would it be more efficient to have an
|
|
Packit |
3f632f |
# array to look up the command line option to send to rateup rather
|
|
Packit |
3f632f |
# than have a long list to check?
|
|
Packit |
3f632f |
push (@exec, '-t') if defined $$rcfg{'options'}{'transparent'}{$router};
|
|
Packit |
3f632f |
push (@exec, '-0') if defined $$rcfg{'options'}{'withzeroes'}{$router};
|
|
Packit |
3f632f |
push (@exec, '-b') if defined $$rcfg{'options'}{'noborder'}{$router};
|
|
Packit |
3f632f |
push (@exec, '-a') if defined $$rcfg{'options'}{'noarrow'}{$router};
|
|
Packit |
3f632f |
push (@exec, '-i') if defined $$rcfg{'options'}{'noi'}{$router};
|
|
Packit |
3f632f |
push (@exec, '-o') if defined $$rcfg{'options'}{'noo'}{$router};
|
|
Packit |
3f632f |
push (@exec, '-l') if defined $$rcfg{'options'}{'logscale'}{$router};
|
|
Packit |
3f632f |
push (@exec, '-x') if defined $$rcfg{'options'}{'expscale'}{$router};
|
|
Packit |
3f632f |
push (@exec, '-m') if defined $$rcfg{'options'}{'secondmean'}{$router};
|
|
Packit |
3f632f |
push (@exec, '-p') if defined $$rcfg{'options'}{'printrouter'}{$router};
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $maxx = $$rcfg{'xsize'}{$router};
|
|
Packit |
3f632f |
my $maxy = $$rcfg{'ysize'}{$router};
|
|
Packit |
3f632f |
my $xscale = $$rcfg{'xscale'}{$router};
|
|
Packit |
3f632f |
my $yscale = $$rcfg{'yscale'}{$router};
|
|
Packit |
3f632f |
my $growright = 0+($$rcfg{'options'}{'growright'}{$router} or 0);
|
|
Packit |
3f632f |
my $bits = 0+($$rcfg{'options'}{'bits'}{$router} or 0);
|
|
Packit |
3f632f |
my $integer = 0+($$rcfg{'options'}{'integer'}{$router} or 0);
|
|
Packit |
3f632f |
my $step = 5*60;
|
|
Packit |
3f632f |
my $rop;
|
|
Packit |
3f632f |
my $ytics = $$rcfg{'ytics'}{$router};
|
|
Packit |
3f632f |
my $yticsf= $$rcfg{'yticsfactor'}{$router};
|
|
Packit |
3f632f |
my $timestrfmt = $$rcfg{'timestrfmt'}{$router};
|
|
Packit |
3f632f |
my $timestrpos = ${MRTG_lib::timestrpospattern}{uc $$rcfg{'timestrpos'}{$router}};
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (not defined $$rcfg{'ylegend'}{$router}){
|
|
Packit |
3f632f |
if ($bits){
|
|
Packit |
3f632f |
$$rcfg{'ylegend'}{$router} = &$LOC("Bits per minute")
|
|
Packit |
3f632f |
if defined $$rcfg{'options'}{'perminute'}{$router};
|
|
Packit |
3f632f |
$$rcfg{'ylegend'}{$router} = &$LOC("Bits per hour")
|
|
Packit |
3f632f |
if defined $$rcfg{'options'}{'perhour'}{$router};
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$$rcfg{'ylegend'}{$router} = &$LOC("Bytes per minute")
|
|
Packit |
3f632f |
if defined $$rcfg{'options'}{'perminute'}{$router};
|
|
Packit |
3f632f |
$$rcfg{'ylegend'}{$router} = &$LOC("Bytes per hour")
|
|
Packit |
3f632f |
if defined $$rcfg{'options'}{'perhour'}{$router};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($$rcfg{'ylegend'}{$router}) {
|
|
Packit |
3f632f |
push (@exec, "l", "[$$rcfg{'ylegend'}{$router}]");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
my $sign = ($$rcfg{'unscaled'}{$router} and $$rcfg{'unscaled'}{$router} =~ /d/) ? 1 : -1;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($$rcfg{'pngtitle'}{$router}) {
|
|
Packit |
3f632f |
push (@exec, "T", "[$$rcfg{'pngtitle'}{$router}]");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($$rcfg{'timezone'}{$router}) {
|
|
Packit |
3f632f |
push (@exec, "Z", "$$rcfg{'timezone'}{$router}");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($$rcfg{'kilo'}{$router}) {
|
|
Packit |
3f632f |
push (@exec, "k", $$rcfg{'kilo'}{$router});
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ($$rcfg{'kmg'}{$router}) {
|
|
Packit |
3f632f |
push (@exec, "K", $$rcfg{'kmg'}{$router});
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ($$rcfg{'weekformat'}{$router}) {
|
|
Packit |
3f632f |
push (@exec, "W", $$rcfg{'weekformat'}{$router});
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
my $SAGE = (time - $main::STARTTIME) / 3600 / 24; # current script age
|
|
Packit |
3f632f |
if (not defined $$opts{'log-only'}){
|
|
Packit |
3f632f |
if (not defined $$rcfg{'suppress'}{$router} or $$rcfg{'suppress'}{$router} !~ /d/) {
|
|
Packit |
3f632f |
# VMS: should work for both now
|
|
Packit |
3f632f |
push (@exec, "i", "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-day.${main::GRAPHFMT}",
|
|
Packit |
3f632f |
$sign*$maxvi, $sign*$maxvo, $maxx, $maxy, ,$xscale, $yscale, $growright, $step, $bits, $ytics, $yticsf, $timestrfmt, $timestrpos);
|
|
Packit |
3f632f |
@mxvls = ("d");
|
|
Packit |
3f632f |
push (@metas, "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-day.${main::GRAPHFMT}",
|
|
Packit |
3f632f |
$$cfg{'interval'});
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (((not -e "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-week.${main::GRAPHFMT}") or
|
|
Packit |
3f632f |
((-M "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-week.${main::GRAPHFMT}") + $SAGE >= 0.5/24)) and
|
|
Packit |
3f632f |
(not defined $$rcfg{'suppress'}{$router} or $$rcfg{'suppress'}{$router} !~/w/)
|
|
Packit |
3f632f |
) {
|
|
Packit |
3f632f |
$step=30*60;
|
|
Packit |
3f632f |
$sign = (defined $$rcfg{'unscaled'}{$router} and $$rcfg{'unscaled'}{$router} =~ /w/) ? 1 : -1;
|
|
Packit |
3f632f |
push (@mxvls , "w");
|
|
Packit |
3f632f |
$rop =(defined $$rcfg{'withpeak'}{$router} and $$rcfg{'withpeak'}{$router} =~ /w/) ? "p" : "i";
|
|
Packit |
3f632f |
push (@exec, $rop ,"$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-week.${main::GRAPHFMT}",
|
|
Packit |
3f632f |
$sign*$maxvi, $sign*$maxvo, $maxx, $maxy, $xscale, $yscale, $growright, $step, $bits, $ytics, $yticsf, $timestrfmt, $timestrpos);
|
|
Packit |
3f632f |
push (@metas, "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-week.${main::GRAPHFMT}", 30);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (((not -e "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-month.${main::GRAPHFMT}") or
|
|
Packit |
3f632f |
(( -M "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-month.${main::GRAPHFMT}") + $SAGE >= 2/24)) and
|
|
Packit |
3f632f |
(not defined $$rcfg{'suppress'}{$router} or $$rcfg{'suppress'}{$router} !~ /m/)) {
|
|
Packit |
3f632f |
$step=2*60*60;
|
|
Packit |
3f632f |
$sign = (defined $$rcfg{'unscaled'}{$router} and $$rcfg{'unscaled'}{$router} =~ /m/) ? 1 : -1;
|
|
Packit |
3f632f |
push (@mxvls , "m");
|
|
Packit |
3f632f |
$rop =(defined $$rcfg{'withpeak'}{$router} and $$rcfg{'withpeak'}{$router} =~ /m/) ? "p" : "i";
|
|
Packit |
3f632f |
push (@exec, $rop ,"$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-month.${main::GRAPHFMT}",
|
|
Packit |
3f632f |
$sign*$maxvi, $sign*$maxvo, $maxx, $maxy, $xscale, $yscale, $growright, $step, $bits, $ytics, $yticsf, $timestrfmt, $timestrpos);
|
|
Packit |
3f632f |
push (@metas, "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-month.${main::GRAPHFMT}", 120);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (((not -e "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-year.${main::GRAPHFMT}") or
|
|
Packit |
3f632f |
(( -M "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-year.${main::GRAPHFMT}") + $SAGE >= 1)) and
|
|
Packit |
3f632f |
(not defined $$rcfg{'suppress'}{$router} or $$rcfg{'suppress'}{$router} !~/y/)) {
|
|
Packit |
3f632f |
$step=24*60*60;
|
|
Packit |
3f632f |
$sign = (defined $$rcfg{'unscaled'}{$router} and $$rcfg{'unscaled'}{$router} =~ /y/) ? 1 : -1;
|
|
Packit |
3f632f |
push (@mxvls , "y");
|
|
Packit |
3f632f |
$rop =(defined $$rcfg{'withpeak'}{$router} and $$rcfg{'withpeak'}{$router} =~ /y/) ? "p" : "i";
|
|
Packit |
3f632f |
push (@exec, $rop, "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-year.${main::GRAPHFMT}",
|
|
Packit |
3f632f |
$sign*$maxvi, $sign*$maxvo, $maxx, $maxy, $xscale, $yscale, $growright, $step, $bits, $ytics, $yticsf, $timestrfmt, $timestrpos);
|
|
Packit |
3f632f |
push (@metas, "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-year.${main::GRAPHFMT}", 1440);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# VMS: this might work now ... or does VMS NOT know about pipes?
|
|
Packit |
3f632f |
# NT doesn't have fork() so an open(xxx,"-|") won't work
|
|
Packit |
3f632f |
# OS2 fork() have bug with socket handles. In RunAsDaemon mode it fail
|
|
Packit |
3f632f |
# after first loop (with "socket operation on non socket" message.
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($MRTG_lib::OS eq 'VMS' or $MRTG_lib::OS eq 'NT' or $MRTG_lib::OS eq 'OS2'){
|
|
Packit |
3f632f |
map { s/"/\\"/; $_ = '"'.$_.'"' if /\s/ } @exec;
|
|
Packit |
3f632f |
open (RATEUP, join (" ", @exec)."|") or
|
|
Packit |
3f632f |
do {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: rateup (".(join " ", @exec ).
|
|
Packit |
3f632f |
") did not work: $!\n";
|
|
Packit |
3f632f |
return;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} elsif ($MRTG_lib::OS eq 'NW'){
|
|
Packit |
3f632f |
map { s/"/\\"/; $_ = '"'.$_.'"' if /\s/ } @exec;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Stuff around because of Perl problems.
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
open (NWPARMS, ">"."$$cfg{'imagedir'}$router.dat") or
|
|
Packit |
3f632f |
do {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: Rateup parameters [$$cfg{'imagedir'}$router.dat] [open] failed.\n";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
return;
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
print NWPARMS join (" ", @exec);
|
|
Packit |
3f632f |
close NWPARMS;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Now run Rateup with path to Parameters.
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
open (RATEUP, "SYS:/Mrtg/bin/rateup -f $$cfg{'imagedir'}$router.dat"."|") or
|
|
Packit |
3f632f |
do {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: SYS:/Mrtg/bin/rateup -f $$cfg{'imagedir'}$router.dat did NOT work.\n";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
return;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$! = undef;
|
|
Packit |
3f632f |
open (RATEUP,"-|") or
|
|
Packit |
3f632f |
do { exec @exec or
|
|
Packit |
3f632f |
warn "$NOW: WARNING: rateup (".(join " ", @exec ).
|
|
Packit |
3f632f |
") did not work: $!\n";
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
debug('log', join(" ", @exec));
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (open (HTML,"<$$cfg{'htmldir'}$$rcfg{'directory'}{$router}$router.$$rcfg{'extension'}{$router}")) {
|
|
Packit |
3f632f |
for ($i=0 ; $i<200 ; $i++) {
|
|
Packit |
3f632f |
last if eof(HTML);
|
|
Packit |
3f632f |
$_= <HTML>;
|
|
Packit |
3f632f |
if (/
|
|
Packit |
3f632f |
$maxin{$1}{$router}=$2 || 0;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (/
|
|
Packit |
3f632f |
$maxout{$1}{$router}=$2 || 0;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (/
|
|
Packit |
3f632f |
$maxpercent{$1}{$router}=$2 || 0;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (/
|
|
Packit |
3f632f |
$avin{$1}{$router}=$2 || 0;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (/
|
|
Packit |
3f632f |
$avout{$1}{$router}=$2 || 0;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (/
|
|
Packit |
3f632f |
$avpercent{$1}{$router}=$2 || 0;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (/
|
|
Packit |
3f632f |
$cuin{$1}{$router}=$2 || 0;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (/
|
|
Packit |
3f632f |
$cuout{$1}{$router}=$2 || 0;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (/
|
|
Packit |
3f632f |
$cupercent{$1}{$router}=$2 || 0;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if (/
|
|
Packit |
3f632f |
$avmxin{$1}{$router}=$2 || 0;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (/
|
|
Packit |
3f632f |
$avmxout{$1}{$router}=$2 || 0;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
close HTML;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
foreach $period (@mxvls) {
|
|
Packit |
3f632f |
$res = <RATEUP>;
|
|
Packit |
3f632f |
if (not defined $res and eof(RATEUP)){
|
|
Packit |
3f632f |
warn "$NOW: ERROR: Skipping webupdates because rateup did not return anything sensible\n";
|
|
Packit |
3f632f |
close RATEUP;
|
|
Packit |
3f632f |
rateupcheck $router;
|
|
Packit |
3f632f |
return;
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
chomp $res;
|
|
Packit |
3f632f |
$maxin{$period}{$router}=sprintf("%.0f",$res || 0);
|
|
Packit |
3f632f |
chomp($res = <RATEUP>);
|
|
Packit |
3f632f |
$maxout{$period}{$router}=sprintf("%.0f",$res || 0);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
|
|
Packit |
3f632f |
chomp($res = <RATEUP>);
|
|
Packit |
3f632f |
$maxpercent{$period}{$router}=sprintf("%.0f",$res || 0);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
chomp($res = <RATEUP>);
|
|
Packit |
3f632f |
$avin{$period}{$router}=sprintf("%.0f",$res || 0);
|
|
Packit |
3f632f |
chomp($res = <RATEUP>);
|
|
Packit |
3f632f |
$avout{$period}{$router}=sprintf("%.0f",$res || 0);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
|
|
Packit |
3f632f |
chomp($res = <RATEUP>);
|
|
Packit |
3f632f |
$avpercent{$period}{$router}=sprintf("%.0f",$res || 0);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
chomp($res = <RATEUP>);
|
|
Packit |
3f632f |
$cuin{$period}{$router}=sprintf("%.0f",$res || 0);
|
|
Packit |
3f632f |
chomp($res = <RATEUP>);
|
|
Packit |
3f632f |
$cuout{$period}{$router}=sprintf("%.0f",$res || 0);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
|
|
Packit |
3f632f |
chomp($res = <RATEUP>);
|
|
Packit |
3f632f |
$cupercent{$period}{$router}=sprintf("%.0f",$res || 0);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
chomp($res = <RATEUP>);
|
|
Packit |
3f632f |
debug('avmx',"avmxin $res");
|
|
Packit |
3f632f |
$avmxin{$period}{$router}=sprintf("%.0f",$res || 0);
|
|
Packit |
3f632f |
chomp($res = <RATEUP>);
|
|
Packit |
3f632f |
debug('avmx',"avmxout $res");
|
|
Packit |
3f632f |
$avmxout{$period}{$router}=sprintf("%.0f",$res || 0);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
close(RATEUP);
|
|
Packit |
3f632f |
rateupcheck $router;
|
|
Packit |
3f632f |
if ( defined $$cfg{'writeexpires'} and $$cfg{'writeexpires'} =~ /^y/i ) {
|
|
Packit |
3f632f |
my($fil,$exp);
|
|
Packit |
3f632f |
while ( $fil = shift(@metas) ) {
|
|
Packit |
3f632f |
$exp = &expistr(shift(@metas));
|
|
Packit |
3f632f |
open(META, ">$fil.meta");
|
|
Packit |
3f632f |
print META "Expires: $exp\n";
|
|
Packit |
3f632f |
close(META);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
|
|
Packit |
3f632f |
return (\%maxin, \%maxout, \%maxpercent, \%avin, \%avout, \%avpercent, \%cuin, \%cuout, \%cupercent, \%avmxin, \%avmxout);
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
return (\%maxin, \%maxout, \%avin, \%avout, \%cuin, \%cuout, \%avmxin, \%avmxout);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
#format 10*$kilo to 10 kB/s
|
|
Packit |
3f632f |
sub fmi {
|
|
Packit |
3f632f |
my($number, $maxbytes, $router, @foo) = @_;
|
|
Packit |
3f632f |
return "?????" unless defined $number;
|
|
Packit |
3f632f |
my($rcfg,$LOC)=@foo;
|
|
Packit |
3f632f |
my @short= ();
|
|
Packit |
3f632f |
my $mul = 1;
|
|
Packit |
3f632f |
if ($$rcfg{'kmg'}{$router}) {
|
|
Packit |
3f632f |
my($i);
|
|
Packit |
3f632f |
if (defined $$rcfg{'shortlegend'}{$router}) {
|
|
Packit |
3f632f |
foreach $i (split(/,/, $$rcfg{'kmg'}{$router})) {
|
|
Packit |
3f632f |
$short[$#short+1] = "$i"."$$rcfg{'shortlegend'}{$router}";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
elsif ($$rcfg{'options'}{'bits'}{$router}) {
|
|
Packit |
3f632f |
foreach $i (split(/,/, $$rcfg{'kmg'}{$router})) {
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'perminute'}{$router}) {
|
|
Packit |
3f632f |
$short[$#short+1] = "$i".&$LOC("b/min");
|
|
Packit |
3f632f |
} elsif ($$rcfg{'options'}{'perhour'}{$router}) {
|
|
Packit |
3f632f |
$short[$#short+1] = "$i".&$LOC("b/h");
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$short[$#short+1] = "$i".&$LOC("b/s");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
$mul= 8;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
foreach $i (split(/,/, $$rcfg{'kmg'}{$router})) {
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'perminute'}{$router}) {
|
|
Packit |
3f632f |
$short[$#short+1] = "$i".&$LOC ("B/min");
|
|
Packit |
3f632f |
} elsif ($$rcfg{'options'}{'perhour'}{$router}) {
|
|
Packit |
3f632f |
$short[$#short+1] = "$i".&$LOC("B/h");
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$short[$#short+1] = "$i".&$LOC("B/s");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
$mul= 1;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
if (defined $$rcfg{'options'}{'bits'}{$router}) {
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'perminute'}{$router}) {
|
|
Packit |
3f632f |
@short = (&$LOC("b/min"),&$LOC("kb/min"),&$LOC("Mb/min"),&$LOC("Gb/min"));
|
|
Packit |
3f632f |
} elsif (defined $$rcfg{'options'}{'perhour'}{$router}) {
|
|
Packit |
3f632f |
@short = (&$LOC("b/h"),&$LOC("kb/h"),&$LOC("Mb/h"),&$LOC("Gb/h"));
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
@short = (&$LOC("b/s"),&$LOC("kb/s"),&$LOC("Mb/s"),&$LOC("Gb/s"));
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
$mul= 8;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'perminute'}{$router}) {
|
|
Packit |
3f632f |
@short = (&$LOC("B/min"),&$LOC("kB/min"),&$LOC("MB/min"),&$LOC("GB/min"));
|
|
Packit |
3f632f |
} elsif ($$rcfg{'options'}{'perhour'}{$router}) {
|
|
Packit |
3f632f |
@short = (&$LOC("B/h"),&$LOC("kB/h"),&$LOC("MB/h"),&$LOC("GB/h"));
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
@short = (&$LOC("B/s"),&$LOC("kB/s"),&$LOC("MB/s"),&$LOC("GB/s"));
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
$mul= 1;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ($$rcfg{'shortlegend'}{$router}) {
|
|
Packit |
3f632f |
@short = ("$$rcfg{'shortlegend'}{$router}",
|
|
Packit |
3f632f |
"k$$rcfg{'shortlegend'}{$router}",
|
|
Packit |
3f632f |
"M$$rcfg{'shortlegend'}{$router}",
|
|
Packit |
3f632f |
"G$$rcfg{'shortlegend'}{$router}");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
my $digits=length("".$number*$mul);
|
|
Packit |
3f632f |
my $divm=0;
|
|
Packit |
3f632f |
#
|
|
Packit |
3f632f |
# while ($digits-$divm*3 > 4) { $divm++; }
|
|
Packit |
3f632f |
# my $divnum = $number*$mul/10**($divm*3);
|
|
Packit |
3f632f |
my $divnum=$number*$mul*$$rcfg{'factor'}{$router};
|
|
Packit |
3f632f |
# while ($divnum/$$rcfg{'kilo'}{$router} >= 10*$$rcfg{'kilo'}{$router} and $divnum<$#short) {
|
|
Packit |
3f632f |
while (($divnum >= 10*$$rcfg{'kilo'}{$router} or $short[$divm] =~ /^-/) and
|
|
Packit |
3f632f |
$divm<$#short) {
|
|
Packit |
3f632f |
$divm++;
|
|
Packit |
3f632f |
$divnum /= $$rcfg{'kilo'}{$router};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
my $perc;
|
|
Packit |
3f632f |
if ($number == 0 || $maxbytes == 0) {
|
|
Packit |
3f632f |
$perc = 0;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$perc = 100/$maxbytes*$number;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if (defined $$rcfg{'options'}{'integer'}{$router}) {
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'nopercent'}{$router}) {
|
|
Packit |
3f632f |
return sprintf("%.0f %s",$divnum,$short[$divm]);
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
return sprintf("%.0f %s (%2.1f%%)",$divnum,$short[$divm],$perc);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
if (defined $$rcfg{'options'}{'nopercent'}{$router}) {
|
|
Packit |
3f632f |
return sprintf("%.1f %s",$divnum,$short[$divm]); # Added: FvW
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
return sprintf("%.1f %s (%2.1f%%)",$divnum,$short[$divm],$perc);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
return sprintf("%.1f %s (%2.1f%%)",$divnum,$short[$divm],$perc);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
sub writehtml {
|
|
Packit |
3f632f |
my($router, $cfg, $rcfg, $maxin, $maxout, $maxpercent,
|
|
Packit |
3f632f |
$avin, $avout, $avmxin, $avmxout, $avpercent,
|
|
Packit |
3f632f |
$cuin, $cuout, $cupercent, $uptime, $name, $LOC) = @_;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my($VERSION,$Today,$peri);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my($persec);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (defined $$rcfg{'options'}{'bits'}{$router}) {
|
|
Packit |
3f632f |
$persec = &$LOC("Bits");
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$persec = &$LOC("Bytes");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Work out the Colour legend
|
|
Packit |
3f632f |
my($leg1, $leg2, $leg3, $leg4, $leg5);
|
|
Packit |
3f632f |
if ($$rcfg{'legend1'}{$router}) {
|
|
Packit |
3f632f |
$leg1 = $$rcfg{'legend1'}{$router};
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'perminute'}{$router}) {
|
|
Packit |
3f632f |
$leg1=&$LOC("Incoming Traffic in $persec per Minute");
|
|
Packit |
3f632f |
} elsif ($$rcfg{'options'}{'perhour'}{$router}) {
|
|
Packit |
3f632f |
$leg1=&$LOC("Incoming Traffic in $persec per Hour");
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$leg1=&$LOC("Incoming Traffic in $persec per Second");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ($$rcfg{'legend2'}{$router}) {
|
|
Packit |
3f632f |
$leg2 = $$rcfg{'legend2'}{$router};
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'perminute'}{$router}) {
|
|
Packit |
3f632f |
$leg2=&$LOC("Outgoing Traffic in $persec per Minute");
|
|
Packit |
3f632f |
} elsif ($$rcfg{'options'}{'perhour'}{$router}) {
|
|
Packit |
3f632f |
$leg2=&$LOC("Outgoing Traffic in $persec per Hour");
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$leg2=&$LOC("Outgoing Traffic in $persec per Second");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ($$rcfg{'legend3'}{$router}) {
|
|
Packit |
3f632f |
$leg3 = $$rcfg{'legend3'}{$router};
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$leg3 = &$LOC("Maximal 5 Minute Incoming Traffic");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ($$rcfg{'legend4'}{$router}) {
|
|
Packit |
3f632f |
$leg4 = $$rcfg{'legend4'}{$router};
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$leg4 = &$LOC("Maximal 5 Minute Outgoing Traffic");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ($$rcfg{'legend5'}{$router}) {
|
|
Packit |
3f632f |
$leg5 = $$rcfg{'legend5'}{$router};
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$leg5 = "(($leg1)/($leg2))*100";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
# Translate the color names
|
|
Packit |
3f632f |
$$rcfg{'col1'}{$router}=&$LOC($$rcfg{'col1'}{$router});
|
|
Packit |
3f632f |
$$rcfg{'col2'}{$router}=&$LOC($$rcfg{'col2'}{$router});
|
|
Packit |
3f632f |
$$rcfg{'col3'}{$router}=&$LOC($$rcfg{'col3'}{$router});
|
|
Packit |
3f632f |
$$rcfg{'col4'}{$router}=&$LOC($$rcfg{'col4'}{$router});
|
|
Packit |
3f632f |
$$rcfg{'col5'}{$router}=&$LOC($$rcfg{'col5'}{$router});
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $dirrel = "../" x ($$rcfg{'directory_web'}{$router} =~ tr|/|/|);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$Today=&$LOC(datestr(time));
|
|
Packit |
3f632f |
$VERSION = "2.17.7";
|
|
Packit |
3f632f |
open (HTML,">$$cfg{'htmldir'}$$rcfg{'directory'}{$router}$router.$$rcfg{'extension'}{$router}") ||
|
|
Packit |
3f632f |
do { warn ("$NOW: WARNING: Writing $router.$$rcfg{'extension'}{$router}: $!");
|
|
Packit |
3f632f |
next };
|
|
Packit |
3f632f |
# this unforutnately confuses old IE greatly ... so we have to comment
|
|
Packit |
3f632f |
# it out for now ... :-(
|
|
Packit |
3f632f |
# print HTML '' . "\n";
|
|
Packit |
3f632f |
print HTML '' . "\n";
|
|
Packit |
3f632f |
print HTML '<html lang="en">' . "\n";
|
|
Packit |
3f632f |
my $interval =$$cfg{'interval'};
|
|
Packit |
3f632f |
my $expiration = &expistr($interval);
|
|
Packit |
3f632f |
my $refresh = defined $$cfg{'refresh'} ? $$cfg{'refresh'} : 300;
|
|
Packit |
3f632f |
my $namestring = &$LOC("the device");
|
|
Packit |
3f632f |
print HTML '' . "\n";
|
|
Packit |
3f632f |
print HTML '' . "\n";
|
|
Packit |
3f632f |
print HTML "\t" . '<head>' . "\n";
|
|
Packit |
3f632f |
print HTML "\t\t" . '<meta charset="' . &$LOC('UTF-8') . '" />' . "\n";
|
|
Packit |
3f632f |
print HTML "\t\t" . '<meta http-equiv="refresh" content="' . "$refresh" . '" />' . "\n";
|
|
Packit |
3f632f |
# Not functional in HTML file in modern web browsers - use HTTP header instead
|
|
Packit |
3f632f |
# <meta http-equiv="pragma" content="no-cache" />
|
|
Packit |
3f632f |
# <meta http-equiv="cache-control" content="no-cache" />
|
|
Packit |
3f632f |
# <meta http-equiv="expires" content="$expiration" />
|
|
Packit |
3f632f |
# <meta http-equiv="generator" content="MRTG $VERSION" />
|
|
Packit |
3f632f |
# <meta http-equiv="date" content="$expiration" />
|
|
Packit |
3f632f |
print HTML "\t\t" . '<title>' . "$$rcfg{'title'}{$router}" . '</title>' . "\n";
|
|
Packit |
3f632f |
foreach $peri (qw(d w m y)) {
|
|
Packit |
3f632f |
print HTML <<"TEXT";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
TEXT
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'dorelpercent'}{$router} and defined $$maxpercent{$peri}{$router}) {
|
|
Packit |
3f632f |
print HTML <<"TEXT";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
TEXT
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
print HTML <<"TEXT";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
TEXT
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
|
|
Packit |
3f632f |
print HTML <<"TEXT";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
TEXT
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
print HTML "\n"
|
|
Packit |
3f632f |
if defined $$cuin{$peri}{$router};
|
|
Packit |
3f632f |
print HTML "\n"
|
|
Packit |
3f632f |
if defined $$cuout{$peri}{$router};
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'dorelpercent'}{$router} and $$cupercent{$peri}{$router} ) {
|
|
Packit |
3f632f |
print HTML <<"TEXT";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
TEXT
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
print HTML <<"TEXT" if $$avmxin{$peri}{$router} and $$avmxout{$peri}{$router};
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
TEXT
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$namestring = "'$name'" if $name;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
defined $$rcfg{backgc}{$router} or $$rcfg{backgc}{$router} = "#fff";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$$rcfg{'rgb1'}{$router} = "" unless defined $$rcfg{'rgb1'}{$router};
|
|
Packit |
3f632f |
$$rcfg{'rgb2'}{$router} = "" unless defined $$rcfg{'rgb2'}{$router};
|
|
Packit |
3f632f |
$$rcfg{'rgb3'}{$router} = "" unless defined $$rcfg{'rgb3'}{$router};
|
|
Packit |
3f632f |
$$rcfg{'rgb4'}{$router} = "" unless defined $$rcfg{'rgb4'}{$router};
|
|
Packit |
3f632f |
$$rcfg{'rgb5'}{$router} = "" unless defined $$rcfg{'rgb5'}{$router};
|
|
Packit |
3f632f |
$$rcfg{'rgb6'}{$router} = "" unless defined $$rcfg{'rgb6'}{$router};
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
print HTML " <style>
|
|
Packit |
3f632f |
body {
|
|
Packit |
3f632f |
background-color: $$rcfg{'backgc'}{$router};
|
|
Packit |
3f632f |
";
|
|
Packit |
3f632f |
if($$rcfg{'backgc'}{$router} eq '#ffffff') {
|
|
Packit |
3f632f |
print HTML " color: #000000;";
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
print HTML " color: #ffffff;";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
div {
|
|
Packit |
3f632f |
border-bottom: 2px solid #aaa;
|
|
Packit |
3f632f |
padding-bottom: 10px;
|
|
Packit |
3f632f |
margin-bottom: 5px;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
div h2 {
|
|
Packit |
3f632f |
font-size: 1.2em;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
div.graph img {
|
|
Packit |
3f632f |
margin: 5px 0;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
div.graph table, div#legend table {
|
|
Packit |
3f632f |
font-size: .8em;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
div.graph table td {
|
|
Packit |
3f632f |
padding: 0 10px;
|
|
Packit |
3f632f |
text-align: right;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
div table .in th, div table td span.in {
|
|
Packit |
3f632f |
color: $$rcfg{'rgb1'}{$router};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
div table .out th, div table td span.out {
|
|
Packit |
3f632f |
color: $$rcfg{'rgb2'}{$router};
|
|
Packit |
3f632f |
}";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
div table .inpeak th {
|
|
Packit |
3f632f |
color: $$rcfg{'rgb3'}{$router};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
div table .outpeak th {
|
|
Packit |
3f632f |
color: $$rcfg{'rgb4'}{$router};
|
|
Packit |
3f632f |
} " if defined $rcfg->{withpeak}{$router};
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
div table .relpercent th {
|
|
Packit |
3f632f |
color: $$rcfg{'rgb5'}{$router};
|
|
Packit |
3f632f |
}" if ( $$rcfg{'options'}{'dorelpercent'}{$router} );
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
div#legend th {
|
|
Packit |
3f632f |
text-align: right;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
div#footer {
|
|
Packit |
3f632f |
border: none;
|
|
Packit |
3f632f |
font-size: .8em;
|
|
Packit |
3f632f |
font-family: Arial, Helvetica, sans-serif;
|
|
Packit |
3f632f |
width: 476px;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
div#footer img {
|
|
Packit |
3f632f |
border: none;
|
|
Packit |
3f632f |
height: 25px;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
div#footer address {
|
|
Packit |
3f632f |
text-align: right;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
div#footer #version {
|
|
Packit |
3f632f |
margin: 0;
|
|
Packit |
3f632f |
padding: 0;
|
|
Packit |
3f632f |
float: left;
|
|
Packit |
3f632f |
width: 88px;
|
|
Packit |
3f632f |
text-align: right;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
</style>";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# allow for \n in addhead
|
|
Packit |
3f632f |
defined $$rcfg{addhead}{$router} or $$rcfg{addhead}{$router} = "";
|
|
Packit |
3f632f |
defined $$rcfg{pagetop}{$router} or $$rcfg{pagetop}{$router} = "";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (defined $$rcfg{bodytag}{$router}) {
|
|
Packit |
3f632f |
if ($$rcfg{bodytag}{$router} !~ /
|
|
Packit |
3f632f |
$$rcfg{bodytag}{$router} = "<body $$rcfg{bodytag}{$router}>";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$$rcfg{bodytag}{$router} = "<body>";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$$rcfg{addhead}{$router} =~ s/\\n/\n/g if defined $$rcfg{addhead}{$router};
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
print HTML "$$rcfg{'addhead'}{$router}
|
|
Packit |
3f632f |
</head>
|
|
Packit |
3f632f |
";
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
$$rcfg{bodytag}{$router}
|
|
Packit |
3f632f |
$$rcfg{'pagetop'}{$router}
|
|
Packit |
3f632f |
";
|
|
Packit |
3f632f |
print HTML "";
|
|
Packit |
3f632f |
if (defined $$rcfg{'timezone'}{$router}){
|
|
Packit |
3f632f |
print HTML
|
|
Packit |
3f632f |
&$LOC("The statistics were last updated $Today $$rcfg{'timezone'}{$router}");
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
print HTML
|
|
Packit |
3f632f |
&$LOC("The statistics were last updated $Today");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ($uptime and ! $$rcfg{options}{noinfo}{$router}) {
|
|
Packit |
3f632f |
print HTML
|
|
Packit |
3f632f |
", \n".
|
|
Packit |
3f632f |
&$LOC("at which time $namestring had been up for $uptime.")
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
print HTML "";
|
|
Packit |
3f632f |
my %sample= ('d' => "`Daily' Graph (".$interval.' Minute',
|
|
Packit |
3f632f |
'w' => "`Weekly' Graph (30 Minute",
|
|
Packit |
3f632f |
'm' => "`Monthly' Graph (2 Hour",
|
|
Packit |
3f632f |
'y' => "`Yearly' Graph (1 Day");
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my %full = ('d' => 'day',
|
|
Packit |
3f632f |
'w' => 'week',
|
|
Packit |
3f632f |
'm' => 'month',
|
|
Packit |
3f632f |
'y' => 'year');
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $InCo;
|
|
Packit |
3f632f |
if (!(defined $$rcfg{'options'}{'noi'}{$router})) {
|
|
Packit |
3f632f |
if (exists $$rcfg{'legendi'}{$router}) {
|
|
Packit |
3f632f |
if ($$rcfg{'legendi'}{$router} ne "") {
|
|
Packit |
3f632f |
$InCo=$$rcfg{'legendi'}{$router};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$InCo=&$LOC("In");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $OutCo;
|
|
Packit |
3f632f |
if (!(defined $$rcfg{'options'}{'noo'}{$router})) {
|
|
Packit |
3f632f |
if (exists $$rcfg{'legendo'}{$router}) {
|
|
Packit |
3f632f |
if ($$rcfg{'legendo'}{$router} ne "") {
|
|
Packit |
3f632f |
$OutCo=$$rcfg{'legendo'}{$router};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$OutCo=&$LOC("Out");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
my $PercentCo;
|
|
Packit |
3f632f |
if (defined $$rcfg{'legend5'}{$router}) {
|
|
Packit |
3f632f |
if ($$rcfg{'legend5'}{$router} ne "") {
|
|
Packit |
3f632f |
$PercentCo=$$rcfg{'legend5'}{$router};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$PercentCo=&$LOC("Percentage");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
foreach $peri (qw(d w m y)) {
|
|
Packit |
3f632f |
next if defined $$rcfg{'suppress'}{$router} and $$rcfg{'suppress'}{$router} =~/$peri/;
|
|
Packit |
3f632f |
my $gifw;
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
|
|
Packit |
3f632f |
$gifw=sprintf("%.0f",($$rcfg{'xsize'}{$router}*$$rcfg{'xscale'}{$router}+
|
|
Packit |
3f632f |
+100+30) *$$rcfg{'xzoom'}{$router});
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$gifw=sprintf("%.0f",($$rcfg{'xsize'}{$router}*$$rcfg{'xscale'}{$router}
|
|
Packit |
3f632f |
+100) *$$rcfg{'xzoom'}{$router});
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
my $gifh=sprintf("%.0f",($$rcfg{'ysize'}{$router}*$$rcfg{'yscale'}{$router}+35)
|
|
Packit |
3f632f |
*$$rcfg{'yzoom'}{$router});
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# take the image directory away from the html directory to give us relative links
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $imagepath = ( $cfg->{htmldir} ne $cfg->{imagedir} ) ? "$dirrel$$cfg{imagehtml}$$rcfg{directory_web}{$router}" : "";
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
".&$LOC("$sample{$peri}").&$LOC(' Average)')."
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
" . &$LOC("Max") . "
|
|
Packit |
3f632f |
" . &$LOC("Average") . "
|
|
Packit |
3f632f |
" . &$LOC("Current") . "
|
|
Packit |
3f632f |
";
|
|
Packit |
3f632f |
my(@foo)=($rcfg,$LOC);
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
" . $InCo . "
|
|
Packit |
3f632f |
".&fmi($$maxin{$peri}{$router}, $$rcfg{'maxbytes1'}{$router}, $router, @foo)."
|
|
Packit |
3f632f |
".&fmi($$avin{$peri}{$router}, $$rcfg{'maxbytes1'}{$router}, $router, @foo)."
|
|
Packit |
3f632f |
".&fmi($$cuin{$peri}{$router}, $$rcfg{'maxbytes1'}{$router}, $router, @foo)."
|
|
Packit |
3f632f |
" if $InCo;
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
" . $OutCo . "
|
|
Packit |
3f632f |
".&fmi($$maxout{$peri}{$router}, $$rcfg{'maxbytes2'}{$router}, $router, @foo)."
|
|
Packit |
3f632f |
".&fmi($$avout{$peri}{$router}, $$rcfg{'maxbytes2'}{$router}, $router, @foo)."
|
|
Packit |
3f632f |
".&fmi($$cuout{$peri}{$router}, $$rcfg{'maxbytes2'}{$router}, $router, @foo)."
|
|
Packit |
3f632f |
" if $OutCo;
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
" . $PercentCo . "
|
|
Packit |
3f632f |
".sprintf("%0.1f %%",($$maxpercent{$peri}{$router} || 0))."
|
|
Packit |
3f632f |
".sprintf("%0.1f %%",($$avpercent{$peri}{$router} || 0 ))."
|
|
Packit |
3f632f |
".sprintf("%0.1f %%",($$cupercent{$peri}{$router} || 0 ))."
|
|
Packit |
3f632f |
" if ($$rcfg{'options'}{'dorelpercent'}{$router} and $PercentCo);
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
" . &$LOC("Average max 5 min values for $sample{$peri} interval):") . "
|
|
Packit |
3f632f |
$InCo " . &fmi($$avmxin{$peri}{$router}, $$rcfg{'maxbytes1'}{$router}, $router, @foo) . "/
|
|
Packit |
3f632f |
$OutCo " . &fmi($$avmxout{$peri}{$router}, $$rcfg{'maxbytes2'}{$router}, $router, @foo) . "
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
" if ($$rcfg{'options'}{'avgpeak'}{$router} and $InCo and $OutCo);
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
\n";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (!(defined $$rcfg{'options'}{'nolegend'}{$router})) {
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
";
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$$rcfg{'col1'}{$router} ###
|
|
Packit |
3f632f |
$leg1
|
|
Packit |
3f632f |
" if $InCo;
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$$rcfg{'col2'}{$router} ###
|
|
Packit |
3f632f |
$leg2
|
|
Packit |
3f632f |
" if $OutCo;
|
|
Packit |
3f632f |
if ($$rcfg{'withpeak'}{$router}) {
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$$rcfg{'col3'}{$router} ###
|
|
Packit |
3f632f |
$leg3
|
|
Packit |
3f632f |
" if $InCo;
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$$rcfg{'col4'}{$router} ###
|
|
Packit |
3f632f |
$leg4
|
|
Packit |
3f632f |
" if $OutCo;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$$rcfg{'col5'}{$router} ###
|
|
Packit |
3f632f |
$leg5
|
|
Packit |
3f632f |
";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (!(defined $$rcfg{'options'}{'nobanner'}{$router})) {
|
|
Packit |
3f632f |
my $gifPath;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (defined $$cfg{icondir}) {
|
|
Packit |
3f632f |
$gifPath = $$cfg{icondir};
|
|
Packit |
3f632f |
#lets make sure there is a trailing path separator
|
|
Packit |
3f632f |
$gifPath =~ s|/*$|/|;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$gifPath = "$dirrel$$cfg{imagehtml}";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
print HTML<
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$VERSION
|
|
Packit |
3f632f |
<address>
|
|
Packit |
3f632f |
Tobias Oetiker
|
|
Packit |
3f632f |
<tobi\@oetiker.ch>
|
|
Packit |
3f632f |
TEXT
|
|
Packit |
3f632f |
print HTML &$LOC("and");
|
|
Packit |
3f632f |
print HTML<
|
|
Packit |
3f632f |
Dave Rand
|
|
Packit |
3f632f |
<dlr\@bungi.com>
|
|
Packit |
3f632f |
TEXT
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# We don't need this any more.
|
|
Packit |
3f632f |
undef $gifPath;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($MRTG_lib::OS eq 'VMS') {
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
".&$LOC("Ported to OpenVMS Alpha by")." Werner Berger
|
|
Packit |
3f632f |
<werner.berger\@cch.cerberus.ch>";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
# There is not realy any significant portion of code from Studard left and
|
|
Packit |
3f632f |
# none of his addresses work anymore. -- Tobi 2001-06-04
|
|
Packit |
3f632f |
# if ($MRTG_lib::OS eq 'NT') {
|
|
Packit |
3f632f |
# print HTML
|
|
Packit |
3f632f |
# "
|
|
Packit |
3f632f |
# ".&$LOC("Ported to WindowsNT by")."
|
|
Packit |
3f632f |
# <NOBR><small>Stuart Schneider
|
|
Packit |
3f632f |
#
|
|
Packit |
3f632f |
# <schneis\@testlab.orst.edu></NOBR>
|
|
Packit |
3f632f |
# ";
|
|
Packit |
3f632f |
# }
|
|
Packit |
3f632f |
if (
|
|
Packit |
3f632f |
$$cfg{'language'} and
|
|
Packit |
3f632f |
defined($lang2tran::LOCALE{"\L$$cfg{'language'}\E"}) and
|
|
Packit |
3f632f |
($LOC != $lang2tran::LOCALE{"default"}))
|
|
Packit |
3f632f |
{
|
|
Packit |
3f632f |
if (defined($credits::LOCALE{"\L$$cfg{'language'}\E"})) {
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
".$credits::LOCALE{"\L$$cfg{'language'}\E"};
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
print HTML "
|
|
Packit |
3f632f |
".$credits::LOCALE{'default'};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
print HTML <
|
|
Packit |
3f632f |
</address>
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
TEXT
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
print HTML $$rcfg{'pagefoot'}{$router} if defined $$rcfg{'pagefoot'}{$router};
|
|
Packit |
3f632f |
print HTML <
|
|
Packit |
3f632f |
</body>
|
|
Packit |
3f632f |
</html>
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
TEXT
|
|
Packit |
3f632f |
close HTML;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (defined $$cfg{'writeexpires'} and $$cfg{'writeexpires'} =~ /^y/i) {
|
|
Packit |
3f632f |
open(HTMLG, ">$$cfg{'htmldir'}$$rcfg{'directory'}{$router}$router.".
|
|
Packit |
3f632f |
"$$rcfg{'extension'}{$router}.meta") ||
|
|
Packit |
3f632f |
do {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: Writing $$cfg{'htmldir'}$$rcfg{'directory'}{$router}$router.".
|
|
Packit |
3f632f |
"$$rcfg{'extension'}{$router}.meta: $!\n";
|
|
Packit |
3f632f |
next
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
print HTMLG "Expires: $expiration\n";
|
|
Packit |
3f632f |
close(HTMLG);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
sub printusage {
|
|
Packit |
3f632f |
print <
|
|
Packit |
3f632f |
Usage: mrtg <config-file>
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
mrtg-2.17.7 - Multi Router Traffic Grapher
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
Copyright 1995-2006 by Tobias Oetiker
|
|
Packit |
3f632f |
Licensed under the Gnu GPL.
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
If you want to know more about this tool, you might want
|
|
Packit |
3f632f |
to read the docs. You can find everything on the
|
|
Packit |
3f632f |
mrtg website:
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
http://oss.oetiker.ch/mrtg/
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
USAGEDESC
|
|
Packit |
3f632f |
exit(1);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
sub lockit {
|
|
Packit |
3f632f |
my ($lockfile,$templock) = @_;
|
|
Packit |
3f632f |
if ($MRTG_lib::OS eq 'VMS' or $MRTG_lib::OS eq 'NT' or $MRTG_lib::OS eq 'OS2') {
|
|
Packit |
3f632f |
# too sad NT and VMS can't do links we'll do the diletants lock
|
|
Packit |
3f632f |
if (-e $lockfile and not unlink $lockfile) {
|
|
Packit |
3f632f |
my($lockage) = time()-(stat($lockfile))[9];
|
|
Packit |
3f632f |
die "$NOW: ERROR: I guess another mrtg is running. A lockfile ($lockfile)\n".
|
|
Packit |
3f632f |
" aged $lockage seconds is hanging around and I can't remove\n".
|
|
Packit |
3f632f |
" it because another process is still using it.";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
open (LOCK, ">$lockfile") or
|
|
Packit |
3f632f |
die "$NOW: ERROR: Creating lockfile $lockfile: $!\n";
|
|
Packit |
3f632f |
print LOCK "$$\n";
|
|
Packit |
3f632f |
close LOCK;
|
|
Packit |
3f632f |
open (LOCK, "<$lockfile") or
|
|
Packit |
3f632f |
die "$NOW: ERROR: Reading lockfile $lockfile for owner check: $!\n";
|
|
Packit |
3f632f |
my($read)=<LOCK>;
|
|
Packit |
3f632f |
chomp($read);
|
|
Packit |
3f632f |
die "$NOW: ERROR: Someone else just got the lockfile $lockfile\n"
|
|
Packit |
3f632f |
unless $$ == $read;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
# now, lets do it the UNIX way ... Daves work ...
|
|
Packit |
3f632f |
open(LOCK,">$templock") or die "$NOW: ERROR: Creating templock $templock: $!";
|
|
Packit |
3f632f |
$main::Cleanfile = $templock;
|
|
Packit |
3f632f |
if (!link($templock,$lockfile)) { # Lock file exists - deal with it.
|
|
Packit |
3f632f |
my($nlink,$lockage) = (stat($lockfile))[3,9];
|
|
Packit |
3f632f |
$lockage = time() - $lockage;
|
|
Packit |
3f632f |
if ($nlink < 2 or $lockage > 30*60) { #lockfile is alone and old
|
|
Packit |
3f632f |
unlink($lockfile)
|
|
Packit |
3f632f |
|| do{ unlink $templock;
|
|
Packit |
3f632f |
die "$NOW: ERROR: Can't unlink stale lockfile ($lockfile). Permissions?\n"};
|
|
Packit |
3f632f |
link($templock,$lockfile)
|
|
Packit |
3f632f |
|| do{ unlink $templock;
|
|
Packit |
3f632f |
die "$NOW: ERROR: Can't create lockfile ($lockfile).\n".
|
|
Packit |
3f632f |
"Permission problem or another mrtg locking succesfully?\n"};
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
unlink $templock;
|
|
Packit |
3f632f |
die "$NOW: ERROR: It looks as if you are running two copies of mrtg in parallel on\n".
|
|
Packit |
3f632f |
" the same config file. There is a lockfile ($lockfile) and it is\n".
|
|
Packit |
3f632f |
" is only $lockage seconds old ... Check your crontab.\n".
|
|
Packit |
3f632f |
" (/etc/crontab and /var/spool/cron/root) \n"
|
|
Packit |
3f632f |
if $lockage < 4;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
die "$NOW: ERROR: I guess another mrtg is running. A lockfile ($lockfile) aged\n".
|
|
Packit |
3f632f |
"$lockage seconds is hanging around. If you are sure that no other mrtg\n".
|
|
Packit |
3f632f |
"is running you can remove the lockfile\n";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
sub threshmail ($$$$){
|
|
Packit |
3f632f |
my $server = shift;
|
|
Packit |
3f632f |
my $from = shift;
|
|
Packit |
3f632f |
my $to = shift;
|
|
Packit |
3f632f |
my $message = shift;
|
|
Packit |
3f632f |
debug('base',"sending threshmail from $from to $to");
|
|
Packit |
3f632f |
my $smtp = Net::SMTP->new([split /\s*,\s*/, $server],Timeout=>5) or
|
|
Packit |
3f632f |
do { warn "$NOW: ERROR: could not send thresholdmail to $to"; return };
|
|
Packit |
3f632f |
$smtp->mail($from);
|
|
Packit |
3f632f |
$smtp->to(split(/\s*,\s*/, $to));
|
|
Packit |
3f632f |
$smtp->data();
|
|
Packit |
3f632f |
$smtp->datasend($message);
|
|
Packit |
3f632f |
$smtp->dataend();
|
|
Packit |
3f632f |
$smtp->quit;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
sub threshcheck {
|
|
Packit |
3f632f |
# threshold checking by Tom Muggli
|
|
Packit |
3f632f |
# ... fsck'd up but fixed by Juha Laine
|
|
Packit |
3f632f |
my ($cfg,$rcfg,$cfgfile,$router,$cuin,$cuout) = @_;
|
|
Packit |
3f632f |
my $threshfile;
|
|
Packit |
3f632f |
my %cu = ( i=> $cuin, o=>$cuout );
|
|
Packit |
3f632f |
# are we going to keep state ?
|
|
Packit |
3f632f |
if (defined $$cfg{'threshdir'}){
|
|
Packit |
3f632f |
ensureSL(\$$cfg{'threshdir'});
|
|
Packit |
3f632f |
$threshfile = $$cfg{'threshdir'}.(split /\Q$MRTG_lib::SL\E/, $cfgfile)[-1].".$router";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# setup environment for external scripts
|
|
Packit |
3f632f |
if (defined $rcfg->{'threshdesc'}{$router}) {
|
|
Packit |
3f632f |
$ENV{THRESH_DESC}=$rcfg->{'threshdesc'}{$router};
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
delete $ENV{THRESH_DESC};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if (defined $rcfg->{'hwthreshdesc'}{$router}) {
|
|
Packit |
3f632f |
$ENV{HWTHRESH_DESC}=$rcfg->{'hwthreshdesc'}{$router};
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
delete $ENV{HWTHRESH_DESC};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
for my $dir (qw(i o)){ # in and out
|
|
Packit |
3f632f |
my %thresh = (
|
|
Packit |
3f632f |
thresh => $cu{$dir}{d}{$router},
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# if we are looking at an rrd with holtwinters RRAs
|
|
Packit |
3f632f |
# we get a failures count.
|
|
Packit |
3f632f |
hwthresh => $cu{$dir}{d_hwfail}{$router}
|
|
Packit |
3f632f |
);
|
|
Packit |
3f632f |
for my $type (keys %thresh){
|
|
Packit |
3f632f |
for my $bound (qw(min max)){
|
|
Packit |
3f632f |
# it gets set inside the loop because threshval gets modified further
|
|
Packit |
3f632f |
# down in the code
|
|
Packit |
3f632f |
my $threshval = $thresh{$type};
|
|
Packit |
3f632f |
next if not defined $threshval;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $boundval = $rcfg->{$type.$bound.$dir}{$router};
|
|
Packit |
3f632f |
next unless defined $boundval;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $realval = "";
|
|
Packit |
3f632f |
my $realthresh = "";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($boundval =~ s/%$//) { # defined in % of maxbytes
|
|
Packit |
3f632f |
# 2 decimals in %
|
|
Packit |
3f632f |
$realval = "% ($threshval)";
|
|
Packit |
3f632f |
$realthresh = "% (".sprintf("%.1f",($rcfg->{"maxbytes".($dir eq 'i' ? 1 : 2)}{$router} * $boundval / 100)).")";
|
|
Packit |
3f632f |
$threshval = sprintf "%.1f", ($threshval / $rcfg->{"maxbytes".($dir eq 'i' ? 1 : 2)}{$router} * 100); # the new code
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
my $msghead = "";
|
|
Packit |
3f632f |
$msghead = "From: $cfg->{threshmailsender}\nTo: $rcfg->{${type}.'mailaddress'}{$router}"
|
|
Packit |
3f632f |
if $rcfg->{${type}.'mailaddress'}{$router} and $cfg->{threshmailsender};
|
|
Packit |
3f632f |
my $pagetop = $rcfg->{pagetop}{$router} || '';
|
|
Packit |
3f632f |
$pagetop =~ s|.*?||;
|
|
Packit |
3f632f |
$pagetop =~ s|\s*\s*(.*?)\s*(.*?)\s*\s*|$1 $2\n|g;
|
|
Packit |
3f632f |
$pagetop =~ s|\s*<.+?>\s*\n?||g;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $msgbody = <
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$rcfg->{title}{$router}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
Target: $router
|
|
Packit |
3f632f |
Type: $type
|
|
Packit |
3f632f |
Direction: $dir
|
|
Packit |
3f632f |
Bound: $bound
|
|
Packit |
3f632f |
Threshold: $boundval$realthresh
|
|
Packit |
3f632f |
Current: $threshval$realval
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$pagetop
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
MESSAGE
|
|
Packit |
3f632f |
$msgbody .= "\n$rcfg->{$type.'desc'}{$router}\n" if $rcfg->{$type.'desc'}{$router};
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (($bound eq 'min' and $boundval > $threshval) or
|
|
Packit |
3f632f |
($bound eq 'max' and $boundval < $threshval)) {
|
|
Packit |
3f632f |
# threshold was broken...
|
|
Packit |
3f632f |
my $message = <
|
|
Packit |
3f632f |
$msghead
|
|
Packit |
3f632f |
Subject: [MRTG-TH] BROKEN $router $type $bound $dir ( $boundval$realthresh vs $threshval$realval )
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
Threshold BROKEN
|
|
Packit |
3f632f |
----------------
|
|
Packit |
3f632f |
$msgbody
|
|
Packit |
3f632f |
MESSAGE
|
|
Packit |
3f632f |
my @exec = ( $rcfg->{$type.'prog'.$dir}{$router}, $router,
|
|
Packit |
3f632f |
$rcfg->{$type.$bound.$dir}{$router}, $threshval,($rcfg->{$type.'desc'}{$router} ||"No Description"));
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Check if we use the status file or not...
|
|
Packit |
3f632f |
if ( defined $threshfile ) {
|
|
Packit |
3f632f |
if ( not -e $threshfile.".".$type.$bound.uc($dir) ) {
|
|
Packit |
3f632f |
# Create a file to indicate a threshold problem for the time after the problem
|
|
Packit |
3f632f |
open THRESHTOUCH, ">".$threshfile.".".$type.$bound.uc($dir)
|
|
Packit |
3f632f |
or warn "$NOW: WARNING: Creating $threshfile.".$bound.uc($dir).": $!\n";
|
|
Packit |
3f632f |
close THRESHTOUCH;
|
|
Packit |
3f632f |
if (defined $rcfg->{$type.'prog'.$dir}{$router}){
|
|
Packit |
3f632f |
debug('base',"run threshprog$dir: ".(join ",",@exec));
|
|
Packit |
3f632f |
system @exec;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
threshmail $cfg->{threshmailserver},$cfg->{threshmailsender},$rcfg->{$type.'mailaddress'}{$router},$message
|
|
Packit |
3f632f |
if $rcfg->{$type.'mailaddress'}{$router}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
else {
|
|
Packit |
3f632f |
debug('base',"NOT acting on BROKEN threshold since $threshfile.$type$bound$dir exists");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} elsif ( not defined $cfg->{$type.'hyst'} or
|
|
Packit |
3f632f |
($bound eq 'min' and $boundval - $cfg->{$type.'hyst'}* $boundval < $threshval) or
|
|
Packit |
3f632f |
($bound eq 'max' and $boundval + $cfg->{$type.'hyst'}* $boundval > $threshval)
|
|
Packit |
3f632f |
) {
|
|
Packit |
3f632f |
# no threshold dir so run on every 'break'
|
|
Packit |
3f632f |
if (defined $rcfg->{$type.'prog'.$dir}{$router}){
|
|
Packit |
3f632f |
debug('base',"run ${type}prog$dir: ".(join ",",@exec));
|
|
Packit |
3f632f |
system @exec;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
threshmail $cfg->{threshmailserver},$cfg->{threshmailsender},$rcfg->{$type.'mailaddress'}{$router},$message
|
|
Packit |
3f632f |
if $rcfg->{$type.'mailaddress'}{$router};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
# no threshold broken ...
|
|
Packit |
3f632f |
my @exec = ( $rcfg->{$type.'progok'.$dir}{$router}, $router,
|
|
Packit |
3f632f |
$rcfg->{$type.$bound.$dir}{$router}, $threshval);
|
|
Packit |
3f632f |
my $message = <
|
|
Packit |
3f632f |
$msghead
|
|
Packit |
3f632f |
Subject: [MRTG-TH] UN-BROKEN $router $type $bound $dir ( $rcfg->{$type.$bound.$dir}{$router} vs $threshval)
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
Threshold UN-BROKEN
|
|
Packit |
3f632f |
-------------------
|
|
Packit |
3f632f |
$msgbody
|
|
Packit |
3f632f |
MESSAGE
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Check if we use the status file or not...
|
|
Packit |
3f632f |
if ( defined $threshfile ) {
|
|
Packit |
3f632f |
if ( -e $threshfile.".".$type.$bound.uc($dir) ){
|
|
Packit |
3f632f |
unlink "$threshfile.".$type.$bound.uc($dir);
|
|
Packit |
3f632f |
if (defined $rcfg->{$type.'progok'.$dir}{$router}){
|
|
Packit |
3f632f |
debug('base',"run ${type}progok$dir: ".(join ",",@exec));
|
|
Packit |
3f632f |
system @exec;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
threshmail $cfg->{threshmailserver},$cfg->{threshmailsender},$rcfg->{$type.'mailaddress'}{$router},$message
|
|
Packit |
3f632f |
if $rcfg->{$type.'mailaddress'}{$router};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} # for my $bound ...
|
|
Packit |
3f632f |
} # for my $type
|
|
Packit |
3f632f |
} # for my $dir
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
sub getexternal ($) {
|
|
Packit |
3f632f |
my $command = shift;
|
|
Packit |
3f632f |
my $in=undef;
|
|
Packit |
3f632f |
my $out=undef;
|
|
Packit |
3f632f |
my $uptime="unknown";
|
|
Packit |
3f632f |
my $name="unknown";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
open (EXTERNAL , $command."|")
|
|
Packit |
3f632f |
or warn "$NOW: WARNING: Running '$command': $!\n";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
warn "$NOW: WARNING: Could not get any data from external command ".
|
|
Packit |
3f632f |
"'".$command.
|
|
Packit |
3f632f |
"'\nMaybe the external command did not even start. ($!)\n\n" if eof EXTERNAL;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
chomp( $in=<EXTERNAL>) unless eof EXTERNAL;
|
|
Packit |
3f632f |
chomp( $out=<EXTERNAL>) unless eof EXTERNAL;
|
|
Packit |
3f632f |
chomp( $uptime=<EXTERNAL>) unless eof EXTERNAL;
|
|
Packit |
3f632f |
chomp( $name=<EXTERNAL>) unless eof EXTERNAL;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
close EXTERNAL;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# strip returned date
|
|
Packit |
3f632f |
$uptime =~ s/^\s*(.*?)\s*/$1/;
|
|
Packit |
3f632f |
$name =~ s/^\s*(.*?)\s*/$1/;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# do we have numbers in the external programs answer ?
|
|
Packit |
3f632f |
if ( not defined $in ) {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: Problem with External get '$command':\n".
|
|
Packit |
3f632f |
" Expected a Number for 'in' but nothing'\n\n";
|
|
Packit |
3f632f |
} elsif ( $in eq 'UNKNOWN' ) {
|
|
Packit |
3f632f |
$in = undef;
|
|
Packit |
3f632f |
} elsif ( $in !~ /([-+]?\d+(.\d+)?)/ ) {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: Problem with External get '$command':\n".
|
|
Packit |
3f632f |
" Expected a Number for 'in' but got '$in'\n\n";
|
|
Packit |
3f632f |
$in = undef;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$in = $1;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ( not defined $out ) {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: Problem with External get '$command':\n".
|
|
Packit |
3f632f |
" Expected a Number for 'out' but nothing'\n\n";
|
|
Packit |
3f632f |
} elsif ( $out eq 'UNKNOWN' ) {
|
|
Packit |
3f632f |
$out = undef;
|
|
Packit |
3f632f |
} elsif ( $out !~ /([-+]?\d+(.\d+)?)/ ) {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: Problem with External get '$command':\n".
|
|
Packit |
3f632f |
" Expected a Number for 'out' but got '$out'\n\n";
|
|
Packit |
3f632f |
$out = undef;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$out = $1;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
debug('snpo',"External result:".($in||"undef")." out:".($out||"undef")." uptime:".($uptime||"undef")." name:".($name||"undef"));
|
|
Packit |
3f632f |
return ($in,$out,time,$uptime,$name);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
sub getsnmparg ($$$$){
|
|
Packit |
3f632f |
my $confcache = shift;
|
|
Packit |
3f632f |
my $target = shift;
|
|
Packit |
3f632f |
my $cfg = shift;
|
|
Packit |
3f632f |
my $populated = shift;
|
|
Packit |
3f632f |
my $retry = 0;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $hostname = $$target{Host};
|
|
Packit |
3f632f |
my $hostkey = "$$target{Community}\@$$target{Host}$$target{SnmpOpt}";
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if ($$target{ipv4only}) {
|
|
Packit |
3f632f |
if (not ( $hostname =~ /^\d+\.\d+\.\d+\.\d+$/ or gethostbyname $hostname) ){
|
|
Packit |
3f632f |
warn "$NOW: WARNING: Skipping host $hostname as it does not resolve to an IPv4 address\n";
|
|
Packit |
3f632f |
return 'DEADHOST';
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
if($hostname =~ /^\[(.*)\]$/) {
|
|
Packit |
3f632f |
# Numeric IPv6 address. Check that it's valid
|
|
Packit |
3f632f |
$hostname = substr($hostname, 1);
|
|
Packit |
3f632f |
chop $hostname;
|
|
Packit |
3f632f |
if(! inet_pton(AF_INET6(), $hostname)) {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: Skipping host $hostname: invalid IPv6 address\n";
|
|
Packit |
3f632f |
return 'DEADHOST';
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
# Hostname. Look it up
|
|
Packit |
3f632f |
my @res;
|
|
Packit |
3f632f |
my ($too,$port,$otheropts) = split(':', $$target{SnmpOpt}, 3);
|
|
Packit |
3f632f |
$port = 161 unless defined $port;
|
|
Packit |
3f632f |
@res = getaddrinfo($hostname, $port, Socket::AF_UNSPEC(), Socket::SOCK_DGRAM());
|
|
Packit |
3f632f |
if (scalar (@res) < 5) {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: Skipping host $hostname as it does not resolve to an IPv4 or IPv6 address\n";
|
|
Packit |
3f632f |
return 'DEADHOST';
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
RETRY:
|
|
Packit |
3f632f |
my @ifnum = ();
|
|
Packit |
3f632f |
my @OID = ();
|
|
Packit |
3f632f |
# Find apropriate Interface to poll from
|
|
Packit |
3f632f |
for my $i (0..1) {
|
|
Packit |
3f632f |
if ($$target{IfSel}[$i] eq 'If') {
|
|
Packit |
3f632f |
$ifnum[$i] = ".".$$target{Key}[$i];
|
|
Packit |
3f632f |
debug('snpo',"simple If: $ifnum[$i]");
|
|
Packit |
3f632f |
} elsif($$target{IfSel}[$i] eq 'None') {
|
|
Packit |
3f632f |
$ifnum[$i] = "";
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$$target{Key}[$i] =~ s/\s+$//; # no trainling whitespace in keys ...
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (not defined readfromcache($confcache,$hostkey,$$target{IfSel}[$i],$$target{Key}[$i])) {
|
|
Packit |
3f632f |
debug('snpo',"($i) Populate ConfCache for $$target{Host}$$target{SnmpOpt}");
|
|
Packit |
3f632f |
populateconfcache($confcache,"$$target{Community}\@$$target{Host}$$target{SnmpOpt}",$$target{ipv4only},1,$$target{snmpoptions});
|
|
Packit |
3f632f |
$$populated{$hostname} = 1; # set cache population to true for this cycle and host
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if (not defined readfromcache($confcache,$hostkey,$$target{IfSel}[$i],$$target{Key}[$i])) {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: Could not match host:'$$target{Community}\@$$target{Host}$$target{SnmpOpt}' ref:'$$target{IfSel}[$i]' key:'$$target{Key}[$i]'\n";
|
|
Packit |
3f632f |
return 'NOMATCH';
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$ifnum[$i] = ".".readfromcache($confcache,$hostkey,$$target{IfSel}[$i],$$target{Key}[$i]);
|
|
Packit |
3f632f |
debug('snpo',"($i) Confcache Match $$target{Key}[$i] -> $ifnum[$i]");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ($ifnum[$i] !~ /^$|^\.\d+$/) {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: Can not determine".
|
|
Packit |
3f632f |
" ifNumber for $$target{Community}\@$$target{Host}$$target{SnmpOpt} \tref: '$$target{IfSel}[$i]' \tkey: '$$target{Key}[$i]'\n";
|
|
Packit |
3f632f |
return 'NOMATCH';
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
for my $i (0..1) {
|
|
Packit |
3f632f |
# add ifget methodes call for a cross check;
|
|
Packit |
3f632f |
for ($$target{IfSel}[$i]) {
|
|
Packit |
3f632f |
/^Eth$/ && do {
|
|
Packit |
3f632f |
push @OID, "ifPhysAddress".$ifnum[$i]; last
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
/^Ip$/ && do {
|
|
Packit |
3f632f |
push @OID, "ipAdEntIfIndex".".".$$target{Key}[$i];last
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
/^Descr$/ && do {
|
|
Packit |
3f632f |
push @OID, "ifDescr".$ifnum[$i]; last
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
/^Type$/ && do {
|
|
Packit |
3f632f |
push @OID, "ifType".$ifnum[$i]; last
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
/^Name$/ && do {
|
|
Packit |
3f632f |
push @OID, "ifName".$ifnum[$i]; last
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
push @OID ,$$target{OID}[$i].$ifnum[$i];
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
# we also want to know uptime and system name unless we are
|
|
Packit |
3f632f |
if ( not defined $$cfg{nomib2} and $$cfg{logformat} ne 'rrdtool' ) {
|
|
Packit |
3f632f |
if ( $OID[0] !~ /^cache.+$/ and
|
|
Packit |
3f632f |
$OID[0] !~ /^\Q1.3.6.1.4.1.3495.1\E/ ) {
|
|
Packit |
3f632f |
push @OID, qw(sysUptime sysName);
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
push @OID, qw(cacheUptime cacheSoftware cacheVersionId)
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# pull that data
|
|
Packit |
3f632f |
debug('snpo',"SNMPGet from $$target{Community}\@$$target{Host}$$target{SnmpOpt} -- ".(join ",", @OID));
|
|
Packit |
3f632f |
my @ret;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# make sure we have no error messages hanging round.
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
$SNMP_Session::errmsg = undef;
|
|
Packit |
3f632f |
$Net_SNMP_util::ErrorMessage = undef;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my $targtemp = $$target{Community}.'@'.$$target{Host}.$$target{SnmpOpt};
|
|
Packit |
3f632f |
$targtemp = v4onlyifnecessary($targtemp, $$target{ipv4only});
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my @snmpoids = grep !/^(Pseudo|WaLK|GeTNEXT|CnTWaLK)|IndexPOS/, @OID;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
if (defined $$cfg{singlerequest}){
|
|
Packit |
3f632f |
#LH local $BER::pretty_print_timeticks = 0;
|
|
Packit |
3f632f |
foreach my $oid (@snmpoids){
|
|
Packit |
3f632f |
push @ret, snmpget($targtemp,$$target{snmpoptions},$oid);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
@ret = snmpget($targtemp,$$target{snmpoptions},@snmpoids);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
my @newret;
|
|
Packit |
3f632f |
for (@OID) {
|
|
Packit |
3f632f |
/^PseudoZero$/ && do { push @newret, 0; next; };
|
|
Packit |
3f632f |
/^PseudoOne$/ && do { push @newret, 1; next; };
|
|
Packit |
3f632f |
s/^WaLK(\d*)// && do { my $idx = $1 || 0; my $oid=$_;push @newret, (split /:/, (snmpwalk($targtemp,$$target{snmpoptions},$oid))[$idx],2)[1];
|
|
Packit |
3f632f |
debug('snpo',"snmpwalk '$oid' -> ".($newret[-1]||'UNDEF'));next};
|
|
Packit |
3f632f |
s/^GeTNEXT// && do { my $oid=$_;push @newret, (split /:/, snmpgetnext($targtemp,$$target{snmpoptions},$oid),2)[1];
|
|
Packit |
3f632f |
debug('snpo',"snmpgetnext '$oid' -> ".($newret[-1]||'UNDEF'));next};
|
|
Packit |
3f632f |
s/^CnTWaLK// && do { my $oid=$_;my @insts= (snmpwalk($targtemp,$$target{snmpoptions},$_));
|
|
Packit |
3f632f |
undef @insts if( $insts[1] || '') =~/no/i; push @newret, scalar @insts;
|
|
Packit |
3f632f |
debug('snpo',"snmpCountwalk '$oid' -> ".($newret[-1]||'UNDEF'));next};
|
|
Packit |
3f632f |
/IndexPOS.*\.(\d*)/ && do { my $idx=$1; s/IndexPOS/$idx/; s/\.\d*$//; push @newret, snmpget($targtemp,$$target{snmpoptions},$_);
|
|
Packit |
3f632f |
debug('snpo', "snmpget of oid '$_' after replacement of IndexPOS"); next};
|
|
Packit |
3f632f |
push @newret, shift @ret;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
@ret = @newret;
|
|
Packit |
3f632f |
debug('snpo',"SNMPfound -- ".(join ", ", map {"'".($_||"undef")."'"} @ret));
|
|
Packit |
3f632f |
$ret[-2] = $ret[-2].' '.$ret[-1] if $OID[-1] and $OID[-1] eq 'cacheVersionId';
|
|
Packit |
3f632f |
my $time = time;
|
|
Packit |
3f632f |
my @final;
|
|
Packit |
3f632f |
# lets do some reality check
|
|
Packit |
3f632f |
for my $i (0..1) {
|
|
Packit |
3f632f |
# some ifget methodes call for a cross check;
|
|
Packit |
3f632f |
for ($$target{IfSel}[$i]) {
|
|
Packit |
3f632f |
/^Eth$/ && do {
|
|
Packit |
3f632f |
my $bin = shift @ret || 0xff;
|
|
Packit |
3f632f |
my $eth = unpack 'H*', $bin;
|
|
Packit |
3f632f |
my @eth;
|
|
Packit |
3f632f |
while ($eth =~ s/^..//){
|
|
Packit |
3f632f |
push @eth, $&;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
my $phys=join '-', @eth;
|
|
Packit |
3f632f |
if ($phys ne $$target{Key}[$i]) {
|
|
Packit |
3f632f |
debug('snpo', "($i) eth if crosscheck got $phys expected $$target{Key}[$i]");
|
|
Packit |
3f632f |
if (not $retry) {
|
|
Packit |
3f632f |
$retry=1;
|
|
Packit |
3f632f |
# remove broken entry
|
|
Packit |
3f632f |
storeincache($confcache,$hostkey,$$target{IfSel}[$i],$$target{Key}[$i],undef);
|
|
Packit |
3f632f |
debug('repo',"($i) goto RETRY force if cache repopulation");
|
|
Packit |
3f632f |
goto RETRY;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: could not match&get".
|
|
Packit |
3f632f |
" $$target{Host}$$target{SnmpOpt}/$$target{OID}[$i] for Eth $$target{Key}[$i]\n";
|
|
Packit |
3f632f |
return 'NOMATCH';
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
debug ('snpo',"($i) Eth crosscheck OK");
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
/^Ip$/ && do {
|
|
Packit |
3f632f |
my $if = shift @ret || 'none';
|
|
Packit |
3f632f |
if ($ifnum[$i] ne '.'.$if) {
|
|
Packit |
3f632f |
debug('repo', "($i) IP if crosscheck got .$if expected $ifnum[$i]");
|
|
Packit |
3f632f |
if (not $retry) {
|
|
Packit |
3f632f |
$retry=1;
|
|
Packit |
3f632f |
# remove broken entry
|
|
Packit |
3f632f |
storeincache($confcache,$hostkey,$$target{IfSel}[$i],$$target{Key}[$i],undef);
|
|
Packit |
3f632f |
debug('repo',"($i) goto RETRY force if cache repopulation");
|
|
Packit |
3f632f |
goto RETRY;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: could not match&get".
|
|
Packit |
3f632f |
" $$target{Host}$$target{SnmpOpt}/$$target{OID}[$i] for IP $$target{Key}[$i]\n";
|
|
Packit |
3f632f |
return 'NOMATCH';
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
debug ('snpo',"($i) IP crosscheck OK");
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
/^(Descr|Name|Type)$/ && do {
|
|
Packit |
3f632f |
my $descr = shift @ret || 'Empty';
|
|
Packit |
3f632f |
$descr =~ s/[\0- ]+$//; # remove excess spaces and stuff
|
|
Packit |
3f632f |
if ($descr ne $$target{Key}[$i]) {
|
|
Packit |
3f632f |
debug('repo', "($i) $_ if crosscheck got $descr expected $$target{Key}[$i]");
|
|
Packit |
3f632f |
if (not $retry) {
|
|
Packit |
3f632f |
$retry=1;
|
|
Packit |
3f632f |
# remove broken entry
|
|
Packit |
3f632f |
storeincache($confcache,$hostkey,$$target{IfSel}[$i],$$target{Key}[$i],undef);
|
|
Packit |
3f632f |
debug('repo',"($i) goto RETRY force if cache repopulation");
|
|
Packit |
3f632f |
goto RETRY;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: could not match&get".
|
|
Packit |
3f632f |
" $$target{Host}$$target{SnmpOpt}/$$target{OID}[$i] for $_ '$$target{Key}[$i]'\n";
|
|
Packit |
3f632f |
return 'NOMATCH';
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
debug ('snpo',"($i) $_ crosscheck OK");
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
# no sense continuing here ... if there is no data ...
|
|
Packit |
3f632f |
if (defined $SNMP_Session::errmsg and $SNMP_Session::errmsg =~ /no response received/){
|
|
Packit |
3f632f |
$SNMP_Session::errmsg = undef;
|
|
Packit |
3f632f |
warn "$NOW: WARNING: skipping because at least the query for $OID[0] on $$target{Host} did not succeed\n";
|
|
Packit |
3f632f |
return 'DEADHOST';
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if (defined $Net_SNMP_util::ErrorMessage and $Net_SNMP_util::ErrorMessage =~ /No response from remote/){
|
|
Packit |
3f632f |
$Net_SNMP_util::ErrorMessage = undef;
|
|
Packit |
3f632f |
warn "$NOW: WARNING: skipping because at least the query for $OID[0] on $$target{Host} did not succeed\n";
|
|
Packit |
3f632f |
return 'DEADHOST';
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ($$target{OID}[$i] =~ /if(Admin|Oper)Hack/) {
|
|
Packit |
3f632f |
push @final, ((shift @ret) == 1) ? 1:0;
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
push @final, shift @ret;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
my @res = ( @final,$time, @ret);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Convert in and out values to integers with a user-defined subroutine
|
|
Packit |
3f632f |
# specified by the Conversion target key
|
|
Packit |
3f632f |
if( $target->{ Conversion } ) {
|
|
Packit |
3f632f |
foreach my $ri( 0..1 ) {
|
|
Packit |
3f632f |
next unless defined $res[ $ri ];
|
|
Packit |
3f632f |
local $SIG{__DIE__};
|
|
Packit |
3f632f |
my $exp = "&MRTGConversion::$target->{ Conversion }( \$res[\$ri] )";
|
|
Packit |
3f632f |
$res[ $ri ] = eval $exp;
|
|
Packit |
3f632f |
warn "$NOW: WARNING: evaluation of \"$exp\" failed\n$@\n" if $@;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# have some cleanup first, it seems that some agents
|
|
Packit |
3f632f |
# are adding newlines to what they return
|
|
Packit |
3f632f |
map{ $_ =~ s/\n|\r//g if defined $_ } @res;
|
|
Packit |
3f632f |
map{ $_ =~ s/^\s+//g if defined $_ } @res;
|
|
Packit |
3f632f |
map{ $_ =~ s/\s+$//g if defined $_ } @res;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# in and out should be numbers only
|
|
Packit |
3f632f |
for my $ri (0..1){
|
|
Packit |
3f632f |
# for folks using rrdtool I am allowing numbers
|
|
Packit |
3f632f |
# with decimals here
|
|
Packit |
3f632f |
if ( defined $res[$ri] and $res[$ri] !~ /^[-+]?\d+(.\d+)?$/ ) {
|
|
Packit |
3f632f |
warn "$NOW: WARNING: Expected a number but got '$res[$ri]'\n";
|
|
Packit |
3f632f |
$res[$ri] = undef;
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
return @res;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# read target function ...
|
|
Packit |
3f632f |
sub readtargets ($$$) {
|
|
Packit |
3f632f |
my ($confcache,$target,$cfg) = @_;
|
|
Packit |
3f632f |
my $forks = $$cfg{forks};
|
|
Packit |
3f632f |
my $trgnum = $#{$target}+1;
|
|
Packit |
3f632f |
if (defined $forks and $forks > 1 and $trgnum > 1){
|
|
Packit |
3f632f |
$forks = $trgnum if $forks > $trgnum;
|
|
Packit |
3f632f |
my $split = int($trgnum / $forks) + 1;
|
|
Packit |
3f632f |
my @hand;
|
|
Packit |
3f632f |
# get them forks to work ...
|
|
Packit |
3f632f |
for (my $i = 0; $i < $forks;$i++) {
|
|
Packit |
3f632f |
local *D;
|
|
Packit |
3f632f |
my $sleep_count=0;
|
|
Packit |
3f632f |
my $pid;
|
|
Packit |
3f632f |
do {
|
|
Packit |
3f632f |
$pid = open(D, "-|");
|
|
Packit |
3f632f |
unless (defined $pid) {
|
|
Packit |
3f632f |
warn "$NOW: WARNING cannot fork: $!\n";
|
|
Packit |
3f632f |
die "$NOW: ERROR bailing out after 6 failed forkattempts"
|
|
Packit |
3f632f |
if $sleep_count++ > 6;
|
|
Packit |
3f632f |
sleep 10;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} until defined $pid;
|
|
Packit |
3f632f |
if ($pid) { # parent
|
|
Packit |
3f632f |
$hand[$i] = *D; # funky file handle magic ...
|
|
Packit |
3f632f |
debug ('fork',"Parent $$ after fork of child $i");
|
|
Packit |
3f632f |
} else { # child
|
|
Packit |
3f632f |
debug ('fork',"Child $i ($$) after fork");
|
|
Packit |
3f632f |
my $res = "";
|
|
Packit |
3f632f |
my %deadhost;
|
|
Packit |
3f632f |
my %populated;
|
|
Packit |
3f632f |
for (my $ii = $i * $split;
|
|
Packit |
3f632f |
$ii < ($i+1) * $split and $ii < $trgnum;
|
|
Packit |
3f632f |
$ii++){
|
|
Packit |
3f632f |
my $targ = $$target[$ii];
|
|
Packit |
3f632f |
my @res;
|
|
Packit |
3f632f |
if ($$targ{Methode} eq 'EXEC') {
|
|
Packit |
3f632f |
@res = getexternal($$targ{Command});
|
|
Packit |
3f632f |
} else { # parent
|
|
Packit |
3f632f |
if (not $deadhost{$$targ{Community}.$$targ{Host}}) {
|
|
Packit |
3f632f |
@res = getsnmparg($confcache,$targ,$cfg,\%populated);
|
|
Packit |
3f632f |
if ( $res[0] and $res[0] eq 'DEADHOST') {
|
|
Packit |
3f632f |
# guess we got a blank here
|
|
Packit |
3f632f |
@res = ( undef,undef,time,undef,undef);
|
|
Packit |
3f632f |
$deadhost{$$targ{Community}.$$targ{Host}} = 1;
|
|
Packit |
3f632f |
warn "$NOW: WARNING: no data for $$targ{OID}[0]&$$targ{OID}[1]:$$targ{Community}\@$$targ{Host}. Skipping further queries for Host $$targ{Host} in this round.\n"
|
|
Packit |
3f632f |
} elsif ($res[0] and $res[0] eq 'NOMATCH'){
|
|
Packit |
3f632f |
@res = (undef,undef,time,undef,undef);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
@res = ( undef,undef,time,undef,undef);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
for (my $iii=0;$iii<5;$iii++){
|
|
Packit |
3f632f |
if (defined $res[$iii]){
|
|
Packit |
3f632f |
$res .= "$res[$iii]\n";
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$res .= "##UNDEF##\n";
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
debug ('fork',"Child $i ($$) waiting to deliver");
|
|
Packit |
3f632f |
print $res; # we only talk after the work has been done to
|
|
Packit |
3f632f |
# otherwhise we might get blocked
|
|
Packit |
3f632f |
# return updated hosts from confcache
|
|
Packit |
3f632f |
writeconfcache($confcache,'&STDOUT')
|
|
Packit |
3f632f |
if defined $$confcache{___updated};
|
|
Packit |
3f632f |
exit 0;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
# happy reaping ...
|
|
Packit |
3f632f |
my $vin =''; # vector of pipe file-descriptors from children
|
|
Packit |
3f632f |
for (my $i = 0; $i < $forks;$i++) {
|
|
Packit |
3f632f |
vec($vin, fileno($hand[$i]), 1) = 1;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
my $left = $forks;
|
|
Packit |
3f632f |
while ($left) {
|
|
Packit |
3f632f |
my $rout = $vin; # read vector
|
|
Packit |
3f632f |
my $eout = $vin; # exception vector
|
|
Packit |
3f632f |
my $nfound = select($rout, undef, $eout, undef); # no timeout
|
|
Packit |
3f632f |
if (1 > $nfound) {
|
|
Packit |
3f632f |
die sprintf("$NOW: ERROR: select returned %d: $!\n", $nfound);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
for (my $i = 0; $i < $forks; $i++) {
|
|
Packit |
3f632f |
next unless defined $hand[$i] and defined fileno($hand[$i]);
|
|
Packit |
3f632f |
# this does not seem to work reliably
|
|
Packit |
3f632f |
# if (vec($eout, fileno($hand[$i]), 1)) {
|
|
Packit |
3f632f |
# die "$NOW: ERROR: fork $i has died ahead of time?\n";
|
|
Packit |
3f632f |
# }
|
|
Packit |
3f632f |
next unless vec($rout, fileno($hand[$i]), 1);
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
vec($vin, fileno($hand[$i]), 1) = 0; # remove this child fd
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
debug ('fork',"Parent reading child $i");
|
|
Packit |
3f632f |
my $h = $hand[$i];
|
|
Packit |
3f632f |
for (my $ii = $i * $split;
|
|
Packit |
3f632f |
$ii < ($i+1) * $split and $ii < $trgnum;
|
|
Packit |
3f632f |
$ii++){
|
|
Packit |
3f632f |
my $targ = $$target[$ii];
|
|
Packit |
3f632f |
my @res;
|
|
Packit |
3f632f |
for (0..4){
|
|
Packit |
3f632f |
my $line = <$h>; # must be a simple scalar here else it wont work
|
|
Packit |
3f632f |
die "$NOW: ERROR: fork $i has died ahead of time ...\n" if not defined $line;
|
|
Packit |
3f632f |
chomp $line;
|
|
Packit |
3f632f |
# debug ('fork',"reading for $ii $line");
|
|
Packit |
3f632f |
$line = undef if $line eq "##UNDEF##";
|
|
Packit |
3f632f |
push @res,$line;
|
|
Packit |
3f632f |
};
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
($$targ{_IN_},
|
|
Packit |
3f632f |
$$targ{_OUT_},
|
|
Packit |
3f632f |
$$targ{_TIME_},
|
|
Packit |
3f632f |
$$targ{_UPTIME_},
|
|
Packit |
3f632f |
$$targ{_NAME_}) = @res;
|
|
Packit |
3f632f |
if ($] >= 5.0061){
|
|
Packit |
3f632f |
$$targ{_IN_} = Math::BigFloat->new($$targ{_IN_}) if $$targ{_IN_};
|
|
Packit |
3f632f |
$$targ{_OUT_} = Math::BigFloat->new($$targ{_OUT_}) if $$targ{_OUT_};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
# feed confcache entries
|
|
Packit |
3f632f |
my $lasthost ="";
|
|
Packit |
3f632f |
while (<$h>){
|
|
Packit |
3f632f |
chomp;
|
|
Packit |
3f632f |
my ($host,$method,$key,$value) = split (/\t/, $_);
|
|
Packit |
3f632f |
if ($host ne $lasthost){
|
|
Packit |
3f632f |
debug ('fork',"start clearing confcache on first entry for target $host");
|
|
Packit |
3f632f |
clearfromcache($confcache,$host);
|
|
Packit |
3f632f |
debug ('fork',"finished clearing confcache");
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
$lasthost = $host;
|
|
Packit |
3f632f |
storeincache($confcache,$host,$method,$key,$value);
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
close $h;
|
|
Packit |
3f632f |
--$left;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
my %deadhost;
|
|
Packit |
3f632f |
my %populated;
|
|
Packit |
3f632f |
foreach my $targ (@$target) {
|
|
Packit |
3f632f |
if ($$targ{Methode} eq 'EXEC') {
|
|
Packit |
3f632f |
debug('snpo', "run external $$targ{Command}");
|
|
Packit |
3f632f |
($$targ{_IN_},
|
|
Packit |
3f632f |
$$targ{_OUT_},
|
|
Packit |
3f632f |
$$targ{_TIME_},
|
|
Packit |
3f632f |
$$targ{_UPTIME_},
|
|
Packit |
3f632f |
$$targ{_NAME_}) = getexternal($$targ{Command});
|
|
Packit |
3f632f |
} elsif ($$targ{Methode} eq 'SNMP' and not $deadhost{$$targ{Host}}) {
|
|
Packit |
3f632f |
debug('snpo', "run snmpget from $$targ{OID}[0]&$$targ{OID}[1]:$$targ{Community}\@$$targ{Host}");
|
|
Packit |
3f632f |
($$targ{_IN_},
|
|
Packit |
3f632f |
$$targ{_OUT_},
|
|
Packit |
3f632f |
$$targ{_TIME_},
|
|
Packit |
3f632f |
$$targ{_UPTIME_},
|
|
Packit |
3f632f |
$$targ{_NAME_}) = getsnmparg($confcache,$targ,$cfg,\%populated);
|
|
Packit |
3f632f |
if ( $$targ{_IN_} and $$targ{_IN_} eq 'DEADHOST') {
|
|
Packit |
3f632f |
$$targ{_IN_} = undef;
|
|
Packit |
3f632f |
$$targ{_TIME_} =time;
|
|
Packit |
3f632f |
# guess we got a blank here
|
|
Packit |
3f632f |
$deadhost{$$targ{Host}} = 1;
|
|
Packit |
3f632f |
warn "$NOW: WARNING: no data for $$targ{OID}[0]&$$targ{OID}[1]:$$targ{Community}\@$$targ{Host}. Skipping further queries for Host $$targ{Host} in this round.\n"
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ( $$targ{_IN_} and $$targ{_IN_} eq 'NOMATCH') {
|
|
Packit |
3f632f |
$$targ{_IN_} = undef;
|
|
Packit |
3f632f |
$$targ{_TIME_} =time;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
} else {
|
|
Packit |
3f632f |
$$targ{_IN_} = undef;
|
|
Packit |
3f632f |
$$targ{_OUT_} = undef;
|
|
Packit |
3f632f |
$$targ{_TIME_} = time;
|
|
Packit |
3f632f |
$$targ{_UPTIME_} = undef;
|
|
Packit |
3f632f |
$$targ{_NAME_} = undef;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ($] >= 5.008 ){
|
|
Packit |
3f632f |
$$targ{_IN_} = new Math::BigFloat "$$targ{_IN_}" if $$targ{_IN_};
|
|
Packit |
3f632f |
$$targ{_OUT_} = new Math::BigFloat "$$targ{_OUT_}" if $$targ{_OUT_};
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
sub imggen ($) {
|
|
Packit |
3f632f |
my $dir = shift;
|
|
Packit |
3f632f |
if ( ! -r "$dir${main::SL}mrtg-l.png" and open W, ">$dir${main::SL}mrtg-l.png" ){
|
|
Packit |
3f632f |
binmode W;
|
|
Packit |
3f632f |
print W unpack ('u', <<'UUENC');
|
|
Packit |
3f632f |
MB5!.1PT*&@H -24A$4@ #\ 9! , !TA.O' &%!,5$5]9GTT
|
|
Packit |
3f632f |
M79A?8HB(9WFR;6G_=DWM=%35<5R_M[A2 6)+1T0'%F&(ZP 1%)1$%4
|
|
Packit |
3f632f |
M>-JMDKUOPD ,Q:E4]CH?S0PMG8-.$6L1A*YMJ,D<T>Q%5?[_ON>$Y (2$R>=
|
|
Packit |
3f632f |
MY;-^OF=;GNCM\SFY#_#GW$IU0WMP/#O5HSGNW8"9R)/92$NQ\Z:GUDG/@.@!
|
|
Packit |
3f632f |
M)CP#4H\ >LT>)NB!A0]8,"]&0.(#WY92V<\$=FM4
|
|
Packit |
3f632f |
MX.<2+4VH!U01B-LYX#V3B*U(1N 5[K,/?(G,)1!!9-%WX0.HYX7 :0!"]0&4
|
|
Packit |
3f632f |
MMV*/Z"/N@&8$P,N8!:FD[!4\ #7EN$G1
|
|
Packit |
3f632f |
M+KI@K$9V#B"P03V,!\5)T]1T#*A,8P"P.%JZ1USGL%%IPTC.#
|
|
Packit |
3f632f |
M6*MJXQ-D& $-T15AT4V]F='=A
|
|
Packit |
3f632f |
M(#DY+S Y+S Q(&-R:7-T>4!M>7-T:6,N97,N9'5P;VYT+F-O;>WHV? J
|
|
Packit |
3f632f |
M=$58=%-I9VYA='5R90!D,C(W8S
|
|
Packit |
3f632f |
K8ULTB'X .=$58=%!A9V4 -C-X,C4K,"LP&!)XE !)14Y$KD)@@F(Y
|
|
Packit |
3f632f |
UUENC
|
|
Packit |
3f632f |
close W;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ( ! -r "$dir${main::SL}mrtg-m.png" and open W, ">$dir${main::SL}mrtg-m.png" ){
|
|
Packit |
3f632f |
binmode W;
|
|
Packit |
3f632f |
print W unpack ('u', <<'UUENC');
|
|
Packit |
3f632f |
MB5!.1PT*&@H -24A$4@ !D 9! , VQYA0 &%!,5$5]9GTT
|
|
Packit |
3f632f |
M79A588QN9(*7:73_=DWL=%31
|
|
Packit |
3f632f |
M>-IC"$4"!0P$>"E&2B:I,%Z((!"(I$)X88H@GJ :A)<$Y@@*I8)YAA">("N(
|
|
Packit |
3f632f |
M%PYD"#L+"IJ#Y4!FN(86N4',# )J"4TO*R\O!_$"@::'@HTEQ /K _&$0+P
|
|
Packit |
3f632f |
M(.T:6@A2@62?H#B*6TRQN#,
|
|
Packit |
3f632f |
M0W1%6'13;V9T=V%R90! *",I26UA9V5-86=I8VL@-"XR+CD@.3DO,#DO,#$@
|
|
Packit |
3f632f |
M8W)I<W1Y0&UY<W1I8RYE<RYD=7!O;G0N8V]M[>C9\ "IT15AT4VEG;F%T
|
|
Packit |
3f632f |
M=7)E #1E,S8X-S$P,38Q-S)A96%B.3,Y8SEA,F5D-31B86(U@DWZ,@ ET
|
|
Packit |
3f632f |
M15AT1&5L87D ,C4P(RC.$P YT15AT4&%G90 R-7@R-2LP*S"#D2 ?
|
|
Packit |
3f632f |
) $E%3D2N0F""
|
|
Packit |
3f632f |
UUENC
|
|
Packit |
3f632f |
close W;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
if ( ! -r "$dir${main::SL}mrtg-r.png" and open W, ">$dir${main::SL}mrtg-r.png" ){
|
|
Packit |
3f632f |
binmode W;
|
|
Packit |
3f632f |
print W unpack ('u', <<'UUENC');
|
|
Packit |
3f632f |
MB5!.1PT*&@H -24A$4@ 80 9! , ##'$3) &%!,5$4T79@\
|
|
Packit |
3f632f |
M8YQ5=JAPC;>:K\S\_?[5WNFZR-PB%CO! 6)+1T0'%F&(ZP !=5)1$%4
|
|
Packit |
3f632f |
M>-KM6$ESVE@0;BW 58: K_)"YDH(.%=YL/"511)7O""N3AS!WY_^NM^3Q)+,
|
|
Packit |
3f632f |
M4C55DZJ1*2&]U]O7Z\,4T"]__0_A;US.O\7$$#H*PR=R[_'@#? A9X3KLW,K
|
|
Packit |
3f632f |
MNRX_*L=MGK^#PQ)[$USW+J@'U)E,!JI<V>GS9"+RG0^B!(NDM,ZMB'G,M_?6
|
|
Packit |
3f632f |
MF@^[_#7D[U)*!V_N!#+4$)>M@+Z(.J/1)PNAI4]=5K# 0_,)'Z(4UXH*A<#/
|
|
Packit |
3f632f |
M2SQ\3+?[=!F4Q&M?Z!8@2-?4X+O*L^Q\$PPQ;MA.R= 65RRWR/:[U&#PTVR_
|
|
Packit |
3f632f |
MR4*JI#3?9#E-$U)#W)5*GE&3[Y&!T%P+?QR2)U;UUOB(0@A0"-Z*.AOVC)=^
|
|
Packit |
3f632f |
MY=L&-T/L"$G !,KBW"V-3PU[.\8W@5N7J)W(?L'&WB5LP6_*X10OP+2L21G/
|
|
Packit |
3f632f |
MH7OA=#:1&M)F-1FI\^A+8B&H %;A+\U>LP8A)HN^RZOC9^BZY#=#_&10NA8"
|
|
Packit |
3f632f |
M.5E !^R7H/2R=0G!6PH%1\%-!W@<"GU+PN4Q.Z2D6-K!2-;D]-=J"-2H?&C>
|
|
Packit |
3f632f |
M7"B$ABCW."HV-PX@%"6$YHS<3:@.K!$K2;N"4-0A\)X'.R[?%R4$MXQ"TT9,
|
|
Packit |
3f632f |
M7*Y:IP)!8N0L=Z0IVUJH(9!51H%B1)9A]$%,S3QB[_P0 EA;B\ W*KM/%?%Q
|
|
Packit |
3f632f |
M%*@8'$*0K?Y@54'0*+ !XZ@&P;C'2N$W?SU&\BX"Z"YKH08ATBB,^WCHW[U5
|
|
Packit |
3f632f |
MCK6U$!U'H3$WA9<<1\%+2I8R"H:]@ZT=Q8%9LK1%Z!1AA< XH902XAM@X#<;
|
|
Packit |
3f632f |
MA?;J) HL-F[!KJ*U%KC:D
|
|
Packit |
3f632f |
M4XWWZ^$U)]+-]? "M9#5YI*_+%^LE''@S[5Q]&951\J&PYL0-FJ],-<4J>DD
|
|
Packit |
3f632f |
M_NQ\.9M$RD9?TE!AX\HJ8E,+IJE^'Q6+.H1X\K#A;V\FI.B6F=)&B$+E>'9T
|
|
Packit |
3f632f |
M51>-EPD:$VVE;#C>'CJ2:=.FJ?9>1_'20-CQ'_ESAN"5Y?Q4LT'=SFS?^.7*
|
|
Packit |
3f632f |
MYFU%;!(IFTP>!K!Q%=8AL.)7D@8/AL;K:#3A#LW#*>0H> <0(-"]YF!:*>X2
|
|
Packit |
3f632f |
MUG&GD;D08Z0] ,((4XWG0O;)0-@2UTPW8@V^G0NG46BO^FNB,@I.7A$?EO.W
|
|
Packit |
3f632f |
MK+1)V<4R&H<$E]MR-K7@GD!HB;DL!4G%N>VP;?YJCPE?\''#<:4C!?S7?-IH
|
|
Packit |
3f632f |
MXG%'2N"B.&2Y/^M(*ZE!6PM.]L..5#4997
|
|
Packit |
3f632f |
M+B$% [N;Y?E&PQ<80[RJG)_Z(@Q;TERV&)DG48AJY>R@5W:5"SWE* JV([U5
|
|
Packit |
3f632f |
M*6W8H>EBM=_O>9B8CF2C0)M:.1L)@-*(!$_\^+C?S8TF.FJJO;6?& AP20*A
|
|
Packit |
3f632f |
MB6DR[*FS':G[7)5<
|
|
Packit |
3f632f |
M^! "2],!%$B88CAS9?S S>_,&2F1-N>:+LBJ2^+#Z1Q1?WV02(3PR2/
|
|
Packit |
3f632f |
M8Q.O/]<@&#R
|
|
Packit |
3f632f |
M3V<3W\H#'^=H&(1Z-F<D4PNA"F+#Y+TKRSC#,!DG/8=#*D;C73LC60B>'*IX
|
|
Packit |
3f632f |
M=,_1!P+ %2,A]5Q'TBSR49QN_$P5\?$9Z>2 P=;DXN8B..I(+ 2/'76SBU,P
|
|
Packit |
3f632f |
MC9=6BD28R\^O)=+1&2E2"#/C%CX7M++)J&#SFMP*GD^F,_SCC+.'42'H+;&)
|
|
Packit |
3f632f |
M0LH]YTU8>HM#"!3_GI@4.:R%*_3\U\EC:M+I8_I]-,T&9*3H0:4U/RYG:-+9
|
|
Packit |
3f632f |
M):7)9D,JX$_9*=,TW>)74"X0F@ Y50B83W?\'H!$"]80*XF;"P2P>%NUJ&2_
|
|
Packit |
3f632f |
M?-51V7N3)7)?E!]B_$V:OMMJ^,+CZMYPMK??9;'SXBG"J;4C%PBPVX5^T]1"
|
|
Packit |
3f632f |
M6U-M/;K_[#>U>Q4<$?_I=?&SS>NP_(5\X=Z<
|
|
Packit |
3f632f |
MO\3U!QLJ>FT="M4^ 0W1%6'13;V9T=V%R90! *",I26UA9V5-86=I8VL@
|
|
Packit |
3f632f |
M-"XR+CD@.3DO,#DO,#$@8W)I<W1Y0&UY<W1I8RYE<RYD=7!O;G0N8V]M[>C9
|
|
Packit |
3f632f |
M\ "IT15AT4VEG;F%T=7)E #$R,3
|
|
Packit |
3f632f |
M9F,T,S9ELPXRP0 ]T15AT4&%G90 S.#AX,C4K,"LP4K-IB0 !)14Y$
|
|
Packit |
3f632f |
$KD)@@C9E
|
|
Packit |
3f632f |
UUENC
|
|
Packit |
3f632f |
close W;
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
}
|
|
Packit |
3f632f |
|
|
Packit |
3f632f |
# Local Variables:
|
|
Packit |
3f632f |
# mode: cperl
|
|
Packit |
3f632f |
# eval: (cperl-set-style "PerlStyle")
|
|
Packit |
3f632f |
# mode: flyspell
|
|
Packit |
3f632f |
# mode: flyspell-prog
|
|
Packit |
3f632f |
# End:
|
|
Packit |
3f632f |
#
|
|
Packit |
3f632f |
# vi: sw=4
|