#!/usr/bin/perl -w # vim:ts=4:sw=4:tw=78 # Update the network traffic log every minute # * * * * * dt=`perl -e'print(time()." ".scalar(localtime(time))."\n");'`;grep : * /proc/net/dev|sed -e"s/^/$dt /" >> /var/log/netraf.log use strict; use lib "/home/system/nagios/libexec" ; use vars qw($PROGNAME); use utils qw (%ERRORS &print_revision &support); use Getopt::Long; use constant NETLOG => '/var/log/netraf.log'; use constant RECLEN => 161; use constant RECS => 6; use constant STALE => 60; # Log considered stale after 60 seconds use constant COLS => qw(RXbytes RXpackets RXerrs RXdrop RXfifo RXframe RXcompressed RXmulticast TXbytes TXpackets TXerrs TXdrop TXfifo TXcolls TXcarrier TXcompressed); sub print_help (); sub print_usage (); $PROGNAME = 'netraf'; my ($opt_c, $opt_f, $opt_w, $opt_C, $opt_W, $opt_h, $opt_V, $opt_i); $opt_w = 1024; $opt_c = 4096; $opt_W = 1024; $opt_C = 4096; $opt_f = NETLOG; $opt_i = 'eth0'; Getopt::Long::Configure('bundling'); GetOptions( "V" => \$opt_V, "version" => \$opt_V, "h" => \$opt_h, "help" => \$opt_h, "f=s" => \$opt_f, "file" => \$opt_f, "i=s" => \$opt_i, "interface" => \$opt_i, "w=f" => \$opt_w, "warning-tx=f" => \$opt_w, "W=f" => \$opt_W, "warning-rx=f" => \$opt_W, "c=f" => \$opt_c, "critical-tx=f" => \$opt_c, "C=f" => \$opt_C, "critical-rx=f" => \$opt_C); if ($opt_V) { print_revision($PROGNAME, '$Id$'); exit $ERRORS{'OK'}; } if ($opt_h) { print_help(); exit $ERRORS{'OK'}; } $opt_f = shift unless ($opt_f); if (! $opt_f) { print "No file specified\n"; exit $ERRORS{'UNKNOWN'}; } # Examine the file. unless (-f $opt_f) { print "$opt_f: File not found\n"; exit $ERRORS{'UNKNOWN'}; } our %traf; our $age = time - (stat(NETLOG))[9]; open(LOG,'<'.NETLOG) || die sprintf("Unable to open file handle LOG for file %s: %s\n",NETLOG,$!); seek(LOG,(RECLEN*-RECS()),2); while (local $_ = ) { if (my ($unixtime,$datetime,$int,$data) = $_ =~ /^(\d{10}) (.+) (\S+):\s*(.+)/) { my %tmp; @tmp{COLS()} = split(/\s+/,$data); $traf{$int}->{$unixtime} = \%tmp; } } close(LOG) || warn sprintf("Unable to close file handle LOG for file %s: %s\n",NETLOG,$!); for my $int (sort keys %traf) { my $last_unixtime; for my $unixtime (sort keys %{$traf{$int}}) { if ($last_unixtime) { $traf{$int}->{RXkbps} = ($traf{$int}->{$unixtime}->{RXbytes} - $traf{$int}->{$last_unixtime}->{RXbytes})/1024/60; $traf{$int}->{TXkbps} = ($traf{$int}->{$unixtime}->{TXbytes} - $traf{$int}->{$last_unixtime}->{TXbytes})/1024/60; } $last_unixtime = $unixtime; } } my $result = 'OK'; my $errstr = "%s - %s %s throughput exceeds %d (RX %d kbps, TX %d kbps)\n"; if ($age > STALE) { $result = 'CRITICAL'; print "$result - $opt_f is stale; $age seconds old\n"; exit $ERRORS{$result}; } $result = 'WARNING'; if ($traf{$opt_i}->{TXkbps} > $opt_w) { printf($errstr,$result,$opt_i,'TX',$opt_w,$traf{$opt_i}->{RXkbps},$traf{$opt_i}->{TXkbps}); exit $ERRORS{$result}; } if ($traf{$opt_i}->{RXkbps} > $opt_W) { printf($errstr,$result,$opt_i,'RX',$opt_W,$traf{$opt_i}->{RXkbps},$traf{$opt_i}->{RXkbps}); exit $ERRORS{$result}; } $result = 'CRITICAL'; if ($traf{$opt_i}->{TXkbps} > $opt_c) { printf($errstr,$result,$opt_i,'TX',$opt_c,$traf{$opt_i}->{RXkbps},$traf{$opt_i}->{TXkbps}); exit $ERRORS{$result}; } if ($traf{$opt_i}->{RXkbps} > $opt_C) { printf($errstr,$result,$opt_i,'RX',$opt_C,$traf{$opt_i}->{RXkbps},$traf{$opt_i}->{RXkbps}); exit $ERRORS{$result}; } printf("OK - %s throughput is within bounds (RX %d kbps < %d,%d / %d kbps < TX %d,%d)\n", $opt_i,$traf{$opt_i}->{RXkbps},$opt_W,$opt_C, $traf{$opt_i}->{TXkbps},$opt_w,$opt_c); exit $ERRORS{'OK'}; sub print_usage () { print "Usage:\n"; print " $PROGNAME [-w ] [-c ] [-W ] [-C ] -f -i \n"; print " $PROGNAME [-h | --help]\n"; print " $PROGNAME [-V | --version]\n"; } sub print_help () { print_revision($PROGNAME, '$Id$'); print "Copyright (c) 2005 Nicola Worthington\n\n"; print_usage(); print "\n"; print " Throughput must be no more than this\n"; print "\n"; support(); }