#!/usr/local/bin/perl
#
# vi:tabstop=4
#
# packet_report Generate a report from the log of packet throughput
#
# Usage: packet_count [-d]
#
# Cron: 55 23 * * * /usr/local/etc/syswatch/bin/packet_report
#
$OnMac = ! -e '/etc/passwd';
#
# -------------------- Configurable items -------------------
#
#
# Email addrs of who should receive this msg
#
$NOTIFY = 'matt\@metawire.com hosttrafficdroid\@metawire.com';
#
# Hosts to get daily reports from
#
@HostWithData = (
'ptolemy'
'dailystop',
'comet'
'bandit',
'bubbles',
'marilyn',
'buster',
'angstrom',
'ns2',
'ns3',
'hpvectra2',
'dunsany',
'brutus'
'miles'
);
#
# -------------------- Things you MAY need to change -------------------
#
$SW_HOME = "/usr/local/etc/syswatch" if( ! $OnMac );
$SCP = "/usr/local/bin/scp";
#
# -------------------- Everything else should fine ---------------------
#
$SW_HOST = &read_in_contents_of_file( "$SW_HOME/config/hostname" );
chop( $SW_HOST );
@TheMonthNames = ( "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" );
$Today = &month_day ( time );
$DayOfMonth = &day_of_month( time );
$TheLogFile = "/var/log/packet_count/day.$DayOfMonth";
$TMP_DIR ="$SW_HOME/tmp" if( ! $OnMac );
$TMP_FILE ="$TMP_DIR/packet_report.$$";
$MIN_INIT = 9999999;
#
# -------------------- Args -------------------
#
$Debug = $ARGV[ 0 ] eq '-d';
# -------------------- Args -------------------
#
# Mail msg "Subject: " line:
#
$SUBJ ="Host IP traffic for $Today";
#
# Number of lines in graph (everything is scaled
# to fit this):
#
$N_LINES_OF_GRAPH_DATA = 22;
$MAX_BAR_WIDTH = 40;
#
# main
#
&summarize_data();
&create_report( $TMP_FILE );
if( $Debug || $OnMac )
{
print &read_in_contents_of_file( $TMP_FILE );
}
else
{
system( "/usr/lib/sendmail $NOTIFY < $TMP_FILE" )
}
unlink $TMP_FILE;
exit;
#
# end
#
sub summarize_data
{
local ( $host );
foreach $host (@HostWithData)
{
if( $host eq $SW_HOST )
{
$data_file = $TheLogFile;
}
else
{
$data_file = &get_remote_log_file( $host );
}
&read_totals( $host, $data_file );
unlink $data_file if( $host ne $SW_HOST && ! $OnMac );
}
}
#
# read_totals
#
sub read_totals
{
local ( $host,
$log_file ) = @_;
local ( $hr, $n_secs, $n_sent, $n_rcvd, $n_conn, $ind );
#
# Don't have a log file? Then we couldn't get
# it, so don't try to process it
#
#print "log file = $log_file, does ";
#if( ! -e $log_file )
#{
# print "NOT ";
#}
#print "exist.\n";
return if( ! -e $log_file );
#
# Init vals for this host
#
foreach $hr (0..23)
{
$ind = "$host $hr";
$min_hourly_sent{ $ind } = $MIN_INIT;
$max_hourly_sent{ $ind } = 0;
$min_hourly_rcvd{ $ind } = $MIN_INIT;
$max_hourly_rcvd{ $ind } = 0;
$min_hourly_conn{ $ind } = $MIN_INIT;
$max_hourly_conn{ $ind } = 0;
}
#
# Open and read the log file
#
open( LOG, $log_file ) || &fatal_error("Can't open $log_file");
#print "Opened log file ($log_file)\n";
while( <LOG> )
{
next if( /^#/ );
#
# Thu Apr 3 11:16:06 PST 1997 29 524 18 509 17
#
# $hr n_secs n_sent n_rcvd n_conn
if( /... ... .. (..):.* ([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)$/ )
{
$hr = int( $1 );
$n_secs = $2;
$n_sent = $3;
$n_rcvd = $4;
$n_conn = $5;
$ind = "$host $hr";
$min_hourly_sent{ $ind } = &min_of( $n_sent, $n_secs, $min_hourly_sent{ $ind } );
$max_hourly_sent{ $ind } = &max_of( $n_sent, $n_secs, $max_hourly_sent{ $ind } );
$min_hourly_rcvd{ $ind } = &min_of( $n_rcvd, $n_secs, $min_hourly_rcvd{ $ind } );
$max_hourly_rcvd{ $ind } = &max_of( $n_rcvd, $n_secs, $max_hourly_rcvd{ $ind } );
$min_hourly_conn{ $ind } = &min_of( $n_conn, $n_secs, $min_hourly_conn{ $ind } );
$max_hourly_conn{ $ind } = &max_of( $n_conn, $n_secs, $max_hourly_conn{ $ind } );
$total_sent{ $host } += $n_sent;
#print "$host: hr = $hr, n_sent=$n_sent, n_rcvd=$n_rcvd, n_conn=$n_conn, n_secs=$n_secs\n";
$total_rcvd{ $host } += $n_rcvd;
$total_conn{ $host } += $n_conn;
}
else
{
print STDERR "Badly formed line: $_";
#print "Badly formed line: $_";
next;
}
}
#print "total_sent = " . $total_sent{ $host } . "\n";
$MaxBarValue = $total_sent{ $host } if( $total_sent{ $host } > $MaxBarValue );
$MaxBarValue = $total_rcvd{ $host } if( $total_rcvd{ $host } > $MaxBarValue );
$MaxBarValue = $total_conn{ $host } if( $total_conn{ $host } > $MaxBarValue );
close( LOG );
}
#
# create_report
#
# Putting it in the temp file
#
sub create_report
{
local ( $report_file ) = @_;
local ( $host );
open( REPORT, "> $report_file" ) || &fatal_error("Can't open $report_file");
print REPORT "Subject: $SUBJ\n";
print REPORT "Total IP packets (TCP + UDP + ICMP) and TCP connections\n\n";
foreach $host (@HostWithData)
{
if( $total_rcvd{ $host } == 0 && $total_sent{ $host } == 0 && $total_conn{ $host } == 0 )
{
&print_bar_line( $host );
}
else
{
print REPORT "$host:\n";
&print_bar_line( ' rcvd:', $total_rcvd{ $host }, " IP packets" );
&print_bar_line( ' sent:', $total_sent{ $host }, " IP packets" );
&print_bar_line( ' cons:', $total_conn{ $host }, " (TCP)\n" );
}
}
print REPORT "\n";
print REPORT "IP packets per second '.'=min, max Received, Sent, Connections\n";
foreach $host (@HostWithData)
{
print REPORT "\n\n";
print REPORT "$host:\n";
&print_one_host_24_hr_period( $host );
}
close( REPORT );
}
#
# print_bar_line
#
sub print_bar_line
{
local ( $beg_label, $n_val, $end_label ) = @_;
local ( $n_chrs, $i );
print REPORT "$beg_label ";
if( $n_val == 0 && $end_label eq '' )
{
print REPORT "No data\n";
}
else
{
print REPORT "$what ";
$n_chrs = int( $n_val * ($MAX_BAR_WIDTH / $MaxBarValue) );
foreach $i (0..$n_chrs)
{
print REPORT "*";
}
foreach $i (0..$MAX_BAR_WIDTH - $n_chrs)
{
print REPORT ".";
}
printf REPORT ("%8d $end_label\n", $n_val );
}
}
#
# print_one_host_24_hr_period
#
sub print_one_host_24_hr_period
{
local ( $host ) = @_;
local ( $ind, $hr, $max_val, $sent_mark, $rcvd_mark, $conn_mark );
foreach $hr (0..23)
{
$ind = "$host $hr";
$min_hourly_sent{ $ind } = 0 if ( $min_hourly_sent{ $ind } == $MIN_INIT );
$min_hourly_rcvd{ $ind } = 0 if ( $min_hourly_rcvd{ $ind } == $MIN_INIT );
$min_hourly_conn{ $ind } = 0 if ( $min_hourly_conn{ $ind } == $MIN_INIT );
$max_val = $max_hourly_sent{ $ind } if( $max_hourly_sent{ $ind } > $max_val );
$max_val = $max_hourly_rcvd{ $ind } if( $max_hourly_rcvd{ $ind } > $max_val );
$max_val = $max_hourly_conn{ $ind } if( $max_hourly_conn{ $ind } > $max_val );
}
$max_val = $N_LINES_OF_GRAPH_DATA if( $max_val < $N_LINES_OF_GRAPH_DATA );
local ( $scaling ) = $max_val / $N_LINES_OF_GRAPH_DATA;
print REPORT ("-"x78, "|\n" );
for($line=$N_LINES_OF_GRAPH_DATA; $line > -3; $line--)
{
next if( $line == 0 );
if( $line == -1 )
{
print REPORT ("-"x78,"|\n");
next;
}
local ( $value_for_this_line ) = $line * $scaling;
printf REPORT ("%4d| ", int( $value_for_this_line ) ) if( $line > -1 );
print REPORT "hour: " if ( $line == -2 );
foreach $hr (0..23)
{
if( $line == -2 )
{
local ( $start ) = $hr;
$start = "0$hr" if( $hr < 10 );
print REPORT "$start ";
next;
}
$ind = "$host $hr";
if( $line == 1 && $max_hourly_sent{ $ind } > 0 && $max_hourly_sent{ $ind } < (2 * $scaling) )
{ $sent_mark = '*'; }
elsif( $min_hourly_sent{ $ind } >= $value_for_this_line )
{ $sent_mark = '.'; }
elsif( $max_hourly_sent{ $ind } >= $value_for_this_line )
{ $sent_mark = 's'; }
else
{ $sent_mark = ' '; }
if( $line == 1 && $max_hourly_rcvd{ $ind } > 0 && $max_hourly_rcvd{ $ind } < (2 * $scaling) )
{ $rcvd_mark = '*'; }
elsif( $min_hourly_rcvd{ $ind } >= $value_for_this_line )
{ $rcvd_mark = '.'; }
elsif( $max_hourly_rcvd{ $ind } >= $value_for_this_line )
{ $rcvd_mark = 'r'; }
else
{ $rcvd_mark = ' '; }
# if( $line == 1 && $max_hourly_conn{ $ind } > 0 && $max_hourly_conn{ $ind } < (2 * $scaling) )
# { $conn_mark = '*'; }
if( $min_hourly_conn{ $ind } >= $value_for_this_line )
{ $conn_mark = ':'; }
elsif( $max_hourly_conn{ $ind } >= $value_for_this_line )
{ $conn_mark = 'c'; }
else
{ $conn_mark = ' '; }
print REPORT "$rcvd_mark$sent_mark$conn_mark";
}
print REPORT "|\n";
}
print REPORT "-"x78,"|\n";
}
#
# get_remote_log_file
#
# Get the data file from this remote host
#
sub get_remote_log_file
{
local ( $host ) = @_;
local ( $dst ) = "$TMP_DIR/$host.day.$DayOfMonth";
# local ( $cmd ) = "$RCP $host:$TheLogFile $dst";
local ( $cmd ) = "$SCP $host:$TheLogFile $dst";
# system( "$cmd >& /usr/local/etc/syswatch/tmp/packet-out" ); # if ! $OnMac;
local ( $xy ) = `$cmd`;
# print "$cmd = '$xy'\n";
#system( "cat $dst" );
# print "$cmd\n" if $OnMac;
return $dst;
}
# ------------------ Utils -------------------
sub min_of
{
local ( $n, $secs, $current_min ) = @_;
local ( $n_per_sec ) = int( $n / $secs );
$current_min = $n_per_sec if( $n_per_sec < $current_min );
return $current_min;
}
sub max_of
{
local ( $n, $secs, $current_max ) = @_;
local ( $n_per_sec ) = $n / $secs;
$current_max = $n_per_sec if( $n_per_sec > $current_max );
return $current_max;
}
#
# fatal_error
#
# Exit with this message. We want to make sure to
# remove our lock file, so we can run again.
#
sub fatal_error
{
local ( $msg ) = @_;
print STDERR "$msg\n";
exit;
}
#
# read_in_contents_of_file
#
# Return the contents of this file in a string.
#
sub read_in_contents_of_file
{
local ( $file_name ) = @_;
local ( $file_conts );
if( $OnMac )
{
open( SRC, $file_name ) || &fatal_error( "Can't open $file_name" );
while( <SRC> )
{
$file_conts = $file_conts . $_;
}
close( SRC );
}
else
{
$file_conts = `cat $file_name`;
}
return $file_conts;
}
#
# month_day()
#
# If time = "Apr 3" rtn "Apr 3"
#
sub month_day
{
local ( $time_num ) = @_;
local ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime( $time_num );
#print "TheMonthNames[ $mon ] = " . $TheMonthNames[ int( $mon ) ] . "\n";
return "$TheMonthNames[ $mon ] $mday";
}
#
# day_of_month()
#
# Return today's day of the month: if this is Apr 3, rtn "3"
#
sub day_of_month
{
local ( $time_num ) = @_;
local ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime( $time_num );
$mday = "0$mday" if( int( $mday ) < 10 );
return "$mday";
}
|