mirror of
https://github.com/munin-monitoring/contrib.git
synced 2025-07-25 18:38:30 +00:00
perl version not committed?!?
This commit is contained in:
parent
f7fcd35f64
commit
138de37d29
1 changed files with 218 additions and 78 deletions
|
@ -1,12 +1,10 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/perl
|
||||||
|
# -*- perl -*-
|
||||||
|
|
||||||
# Now updated to support 32-bit operating systems
|
=head1 NAME
|
||||||
# Requires bash
|
|
||||||
|
|
||||||
: << =cut
|
|
||||||
|
|
||||||
bandwidth_ - Wildcard-plugin to monitor total network traffic and
|
bandwidth_ - Wildcard-plugin to monitor total network traffic and
|
||||||
predict 30 day bandwidth usage
|
predict 30 day bandwidth usage
|
||||||
|
|
||||||
=head1 CONFIGURATION
|
=head1 CONFIGURATION
|
||||||
|
|
||||||
|
@ -20,16 +18,21 @@ bandwidth_<interface> to this file. E.g.
|
||||||
|
|
||||||
Most likely usage is to monitor an interface connected to your ISP.
|
Most likely usage is to monitor an interface connected to your ISP.
|
||||||
|
|
||||||
|
The suggest option will try and determine if you have any interfaces with a
|
||||||
|
public IP and if so it will suggest monitoring those interfaces. If all
|
||||||
|
IP addresses are private the setup will have to be done manually. Suggest
|
||||||
|
does not handle IPv6 addresses.
|
||||||
|
|
||||||
=head1 USAGE
|
=head1 USAGE
|
||||||
|
|
||||||
Any device found in /proc/net/dev can be monitored. Examples include ipsec*,
|
Any device found in /proc/net/dev can be monitored. Examples include ipsec*,
|
||||||
eth*, irda* and lo.
|
eth*, irda* and lo.
|
||||||
|
|
||||||
Please not that aliases cannot be monitored with this plugin.
|
Please note that aliases cannot be monitored with this plugin.
|
||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
$Id: bandwidth_,v 1.2 2011/09/16 17:54:50 root Exp $
|
$Id: bandwidth_,v 1.35 2012/01/23 20:04:33 root Exp $
|
||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
@ -53,92 +56,229 @@ to be interested in expressing peaks in bytes....
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
# Change to show your outside interface
|
use strict;
|
||||||
INTERFACE=${0##*bandwidth_}
|
use Storable qw(store retrieve);
|
||||||
HISTORY="/var/lib/munin/plugin-state/bandwidth_$INTERFACE.state"
|
use Switch;
|
||||||
|
|
||||||
TOTALUPTIME=0
|
my $interface;
|
||||||
TOTALINPUT=0
|
my $history;
|
||||||
TOTALOUTPUT=0
|
my $counter_input;
|
||||||
OLDUPTIME=0
|
my $counter_output;
|
||||||
OLDINPUT=0
|
my $input;
|
||||||
OLDOUTPUT=0
|
my $output;
|
||||||
|
my $uptime;
|
||||||
|
my $oldest_ts;
|
||||||
|
my $input_30days;
|
||||||
|
my $output_30days;
|
||||||
|
my $perf_ref = {};
|
||||||
|
my $count30 = 2592000; # The number of seconds in 30 days
|
||||||
|
my $unix_ts = time;
|
||||||
|
my $rollover = 4294967295;
|
||||||
|
|
||||||
test -f $HISTORY || touch $HISTORY
|
eval { init(); };
|
||||||
BC=$(which bc)
|
|
||||||
test ${#BC} || (echo "bc not found, please install bc" && exit 1)
|
|
||||||
|
|
||||||
case $1 in
|
sub autoconf {
|
||||||
|
$0 =~ /bandwidth_(.+)*$/;
|
||||||
|
$interface = $1;
|
||||||
|
exit 2 unless defined $interface;
|
||||||
|
$history = "/var/lib/munin/plugin-state/bandwidth_$interface.state";
|
||||||
|
}
|
||||||
|
|
||||||
# I know that "bandwidth is bits and base10 as opposed to bytes and base2.
|
sub bit32or64 {
|
||||||
# However the purpose of this plugin it to monitor your monthly bandwidth
|
if ( $input > $rollover || $output > $rollover ) {
|
||||||
# consumption to make sure you don't go over your ISP's peak. ISP's seem
|
$rollover = 18446744073709551615;
|
||||||
# to be interested in expressing peaks in bytes....
|
}
|
||||||
|
}
|
||||||
|
|
||||||
config)
|
sub retrieve_history {
|
||||||
cat <<'EOM'
|
return (undef) unless ( -r $history );
|
||||||
|
my $store = retrieve($history);
|
||||||
|
while ( my ( $key, $value ) = each(%$store) ) {
|
||||||
|
if ( $unix_ts - $key < $count30 ) {
|
||||||
|
$perf_ref->{$key} = $value;
|
||||||
|
}
|
||||||
|
if ( $key =~ /last/ ) {
|
||||||
|
$perf_ref->{$key} = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub suggest {
|
||||||
|
|
||||||
|
# This only works if one of your interfaces has a public IP,
|
||||||
|
# Otherwise it will fail and you will have to set it manually
|
||||||
|
# Multiple public IP addresses can be detected. It won't
|
||||||
|
# Detect IPv6 addresses.
|
||||||
|
my $locate = readpipe("locate -b '\\ifconfig'");
|
||||||
|
my @ifconfig = readpipe($locate);
|
||||||
|
my @old;
|
||||||
|
my $net = "/proc/net/dev";
|
||||||
|
my @interfaces;
|
||||||
|
-f $net || die "Unable to read $net: $!";
|
||||||
|
open( DEV, "<", $net ) || die "Unable to read $net: $!";
|
||||||
|
|
||||||
|
while (<DEV>) {
|
||||||
|
chomp;
|
||||||
|
split;
|
||||||
|
/Inter|face/ and next;
|
||||||
|
split /:/;
|
||||||
|
push( @interfaces, $_[0] );
|
||||||
|
}
|
||||||
|
close(DEV);
|
||||||
|
|
||||||
|
foreach (@ifconfig) {
|
||||||
|
if (/inet addr:([\d.]+)/) {
|
||||||
|
$1
|
||||||
|
=~ /^(127\.\d+|10\.\d+|172\.(1[6-9]|2\d|3[0-1])|192\.168)(\.\d+){2}$/
|
||||||
|
and next;
|
||||||
|
exists $interfaces[ $old[0] ] and print "$old[0]\n";
|
||||||
|
}
|
||||||
|
@old = split;
|
||||||
|
chomp @old;
|
||||||
|
}
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub store_history {
|
||||||
|
|
||||||
|
# Store the current values to the new old times
|
||||||
|
$perf_ref->{$unix_ts} = {
|
||||||
|
input => $input,
|
||||||
|
output => $output,
|
||||||
|
};
|
||||||
|
$perf_ref->{last} = {
|
||||||
|
counter_input => $counter_input,
|
||||||
|
counter_output => $counter_output,
|
||||||
|
uptime => $uptime,
|
||||||
|
};
|
||||||
|
store( $perf_ref, $history ) || die "Unable to store $history: $!";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub arg {
|
||||||
|
defined( $ARGV[0] ) or return;
|
||||||
|
switch ( $ARGV[0] ) {
|
||||||
|
case 'autoconf' { print "yes\n"; exit 0; }
|
||||||
|
case 'config' { print_config(); }
|
||||||
|
case 'suggest' { suggest(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub print_config {
|
||||||
|
print <<EOM;
|
||||||
graph_title Monthly Bandwidth average
|
graph_title Monthly Bandwidth average
|
||||||
graph_vlabel Bytes
|
graph_vlabel Bytes (per sec)
|
||||||
average.label current average
|
average.label current 30 day average bytes/sec
|
||||||
monthly.label monthly projection
|
monthly.label monthly project based on 30 day average
|
||||||
average.info Your average bandwidth usage based on uptime
|
30dayusage.label monthly usage
|
||||||
monthly.info Your projected monthly bandwidth usage based on uptime
|
average.info Your average network rate based (up to) the last 30 days of data
|
||||||
|
monthly.info Your projected monthly network rate based on your average network rate
|
||||||
|
30dayusage.info Your usage for the last 30 days.
|
||||||
graph_category network
|
graph_category network
|
||||||
graph_args --base 1024 -l 0
|
graph_args --base 1024 -l 0
|
||||||
graph_info This graph show your current average bandwidth usage and projected 30 day average based on your current consumption
|
graph_info This graph show your current average bandwidth usage and projected 30 day average based on your last 30 day usage.
|
||||||
average.warning 8944269393.92
|
average.warning 103563
|
||||||
monthly.warning 268435456000
|
monthly.warning 268435456000
|
||||||
|
30dayusage.warning 268435456000
|
||||||
EOM
|
EOM
|
||||||
exit 0;;
|
exit 0;
|
||||||
esac
|
}
|
||||||
|
|
||||||
source $HISTORY
|
sub read_traffic {
|
||||||
|
open( my $rx, "<", "/sys/class/net/$interface/statistics/rx_bytes" )
|
||||||
|
|| die "Unable to read: $!";
|
||||||
|
$counter_input = <$rx>;
|
||||||
|
chomp $counter_input;
|
||||||
|
close($rx);
|
||||||
|
open(my $tx , "<", "/sys/class/net/$interface/statistics/tx_bytes" )
|
||||||
|
|| die "Unable to read: $!";
|
||||||
|
$counter_output = <$tx>;
|
||||||
|
chomp $counter_output;
|
||||||
|
close(DEV);
|
||||||
|
}
|
||||||
|
|
||||||
INPUT=$(ifconfig $INTERFACE|grep bytes|awk '{print $2}'|sed s/bytes://g)
|
sub uptime {
|
||||||
OUTPUT=$(ifconfig $INTERFACE|grep bytes|awk '{print $6}'|sed s/bytes://g)
|
my $puptime = "/proc/uptime";
|
||||||
|
open( TIME, "<", $puptime ) || die "Unable to read $puptime: $!";
|
||||||
|
while (<TIME>) {
|
||||||
|
split;
|
||||||
|
$uptime = @_[0];
|
||||||
|
}
|
||||||
|
close(TIME);
|
||||||
|
chomp $uptime;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub update_stats {
|
||||||
|
|
||||||
UPTIME=$(cat /proc/uptime | cut -d'.' -f1-1)
|
# First determine if this has ever run before. If not set initial values
|
||||||
|
# to 0.
|
||||||
|
if ( defined $perf_ref->{last}->{uptime} ) {
|
||||||
|
|
||||||
# Dealing with a reboot. I'm not worrying about a uptime rollover.
|
# Compute the new totals, caused by reboot. As uptime is measures in
|
||||||
# Evidently uptime is 64-bit even on 32-bit machines using "jiffies".
|
# 64-bit jiffies, the chance of a counter rollover is remote
|
||||||
if [[ $OLDUPTIME -gt $UPTIME ]]; then
|
if ( $perf_ref->{last}->{uptime} > $uptime ) {
|
||||||
TOTALUPTIME=$(($TOTALUPTIME+$UPTIME))
|
$input = $counter_input;
|
||||||
TOTALINPUT=$(($TOTALINPUT+$INPUT))
|
$output = $counter_output;
|
||||||
TOTALOUTPUT=$(($TOTALOUTPUT+$OUTPUT))
|
|
||||||
|
|
||||||
# Dealing with a 32-bit counter rollover. This is detected by comparing
|
}
|
||||||
# The last value with the new value and the uptime. Else update normally
|
else {
|
||||||
|
if ( $perf_ref->{last}->{counter_input} > $counter_input ) {
|
||||||
|
$input =
|
||||||
|
$counter_input
|
||||||
|
+ $rollover
|
||||||
|
- $perf_ref->{last}->{counter_input};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$input = $counter_input - $perf_ref->{last}->{counter_input};
|
||||||
|
}
|
||||||
|
if ( $perf_ref->{last}->{counter_output} > $counter_output ) {
|
||||||
|
$output =
|
||||||
|
$counter_output
|
||||||
|
+ $rollover
|
||||||
|
- $perf_ref->{last}->{counter_output};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$output =
|
||||||
|
$counter_output - $perf_ref->{last}->{counter_output};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$input = 0;
|
||||||
|
$output = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else
|
sub sum_old {
|
||||||
|
$oldest_ts = $unix_ts;
|
||||||
|
while ( my ( $key, $value ) = each(%$perf_ref) ) {
|
||||||
|
$key =~ /last/ and next;
|
||||||
|
$input_30days += $perf_ref->{$key}->{'input'};
|
||||||
|
$output_30days += $perf_ref->{$key}->{'output'};
|
||||||
|
$key < $oldest_ts and $oldest_ts = $key
|
||||||
|
}
|
||||||
|
$input_30days += $input;
|
||||||
|
$output_30days += $output;
|
||||||
|
}
|
||||||
|
|
||||||
TOTALUPTIME=$(($TOTALUPTIME+$UPTIME-$OLDUPTIME))
|
sub munin_output {
|
||||||
|
my $period = $unix_ts - $oldest_ts;
|
||||||
|
my $total30 = $input_30days + $output_30days;
|
||||||
|
my $average30 = $total30 / $period;
|
||||||
|
print "average.value $average30\n";
|
||||||
|
print "monthly.value " . $average30 * $count30 . "\n";
|
||||||
|
print "30dayusage.value $total30\n";
|
||||||
|
}
|
||||||
|
|
||||||
if [[ $OLDINPUT -gt $INPUT ]]; then
|
sub init {
|
||||||
TOTALINPUT=$(($TOTALINPUT+$INPUT))
|
arg();
|
||||||
else
|
autoconf();
|
||||||
TOTALINPUT=$((TOTALINPUT+$INPUT-$OLDINPUT))
|
retrieve_history();
|
||||||
fi
|
read_traffic();
|
||||||
if [[ $OLDOUTPUT -gt $OUTPUT ]]; then
|
bit32or64();
|
||||||
TOTALOUTPUT=$((TOTALOUTPUT+$OUTPUT))
|
uptime();
|
||||||
else
|
update_stats();
|
||||||
TOTALOUTPUT=$((TOTALOUTPUT+$OUTPUT-$OLDOUTPUT))
|
sum_old();
|
||||||
fi
|
munin_output();
|
||||||
fi
|
store_history();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TOTAL=$(($TOTALINPUT+$TOTALOUTPUT))
|
|
||||||
UPV=$(echo "scale=3;$TOTALUPTIME/60/60/24"|bc)
|
|
||||||
DAILY=$(echo "scale=3;$TOTAL/$UPV"|bc)
|
|
||||||
MONTHLY=$(echo "scale=3;$DAILY*30"|bc)
|
|
||||||
|
|
||||||
echo "TOTALUPTIME=$TOTALUPTIME" > $HISTORY
|
|
||||||
echo "OLDUPTIME=$UPTIME" >> $HISTORY
|
|
||||||
echo "TOTALINPUT=$TOTALINPUT" >> $HISTORY
|
|
||||||
echo "OLDINPUT=$INPUT" >> $HISTORY
|
|
||||||
echo "TOTALOUTPUT=$TOTALOUTPUT" >> $HISTORY
|
|
||||||
echo "OLDOUTPUT=$OUTPUT" >> $HISTORY
|
|
||||||
|
|
||||||
echo "average.value $DAILY"
|
|
||||||
echo "monthly.value $MONTHLY"
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue