diff --git a/plugins/other/bandwidth_ b/plugins/other/bandwidth_ index 6d73fdbf..99a4fc39 100755 --- a/plugins/other/bandwidth_ +++ b/plugins/other/bandwidth_ @@ -1,12 +1,10 @@ -#!/bin/bash +#!/usr/bin/perl +# -*- perl -*- -# Now updated to support 32-bit operating systems -# Requires bash - -: << =cut +=head1 NAME bandwidth_ - Wildcard-plugin to monitor total network traffic and -predict 30 day bandwidth usage + predict 30 day bandwidth usage =head1 CONFIGURATION @@ -20,16 +18,21 @@ bandwidth_ to this file. E.g. 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 Any device found in /proc/net/dev can be monitored. Examples include ipsec*, 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 -$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 @@ -53,92 +56,229 @@ to be interested in expressing peaks in bytes.... =cut -# Change to show your outside interface -INTERFACE=${0##*bandwidth_} -HISTORY="/var/lib/munin/plugin-state/bandwidth_$INTERFACE.state" +use strict; +use Storable qw(store retrieve); +use Switch; -TOTALUPTIME=0 -TOTALINPUT=0 -TOTALOUTPUT=0 -OLDUPTIME=0 -OLDINPUT=0 -OLDOUTPUT=0 +my $interface; +my $history; +my $counter_input; +my $counter_output; +my $input; +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 -BC=$(which bc) -test ${#BC} || (echo "bc not found, please install bc" && exit 1) +eval { init(); }; -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. -# However the purpose of this plugin it to monitor your monthly bandwidth -# consumption to make sure you don't go over your ISP's peak. ISP's seem -# to be interested in expressing peaks in bytes.... +sub bit32or64 { + if ( $input > $rollover || $output > $rollover ) { + $rollover = 18446744073709551615; + } +} - config) - cat <<'EOM' +sub retrieve_history { + 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 () { + 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 <; + 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) -OUTPUT=$(ifconfig $INTERFACE|grep bytes|awk '{print $6}'|sed s/bytes://g) +sub uptime { + my $puptime = "/proc/uptime"; + open( TIME, "<", $puptime ) || die "Unable to read $puptime: $!"; + while (