[alt.sources] Log summaries

jv@mh.nl (Johan Vromans) (04/16/91)

>  Has anybody written a program (Perl?) to parse UUCP log files, to
> give an idea how much each UUCP connection's being used, and for how
> long?

Reposting time...

---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 04/16/1991 07:06 UTC by jv@largo
# Source directory /u1/users/jv
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   5454 -r--r--r-- uutraf.pl
#
# ============= uutraf.pl ==============
if test -f 'uutraf.pl' -a X"$1" != X"-c"; then
	echo 'x - skipping uutraf.pl (File already exists)'
else
echo 'x - extracting uutraf.pl (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'uutraf.pl' &&
#!/usr/bin/perl
eval "exec /usr/bin/perl -S $0 $*"
X  if $running_under_some_shell;
do verify_perl_version (3001);
X
# @(#)@ uutraf	1.4 - uutraf.pl
#
# UUCP Traffic Analyzer
#
# Reads /usr/lib/uucp/.Admin/xferstats, and generates a report from it.
# Also understands Ultrix SYSLOG format.
#
# Created by Johan Vromans <jv@mh.nl>
# Loosely based on an idea by Greg Hackney (hack@texbell.swbt.com)
X
# Usage: uutraf [xferstats]
X
$type = "unknown";
X
if ( $#ARGV >= 0 ) {
X    open (STDIN, $ARGV[0]) || die "Cannot open $ARGV[0]";
X    open (IN, $ARGV[0]) || die "Cannot open $ARGV[0]";
X    $line = <IN>;
X    split (/ /, $line);
X    $type = ($_[0] =~ /!/) ? "HDB" : "U";
}
elsif ( -r "/usr/spool/uucp/.Admin/xferstats" ) {
X    open (STDIN, "/usr/spool/uucp/.Admin/xferstats");
X    $type = "HDB";
}
elsif ( -r "/usr/spool/uucp/SYSLOG" ) {
X    open (STDIN, "/usr/spool/uucp/SYSLOG");
X    $type = "U";
}
else { die "Sorry, don't know what"; }
X
if ( $type eq "HDB" ) {
X    $pat = "([^!]+)![^(]+\\(([-0-9:/]+)\\).+([<>])-? (\\d+) / (\\d+)\\.(\\d+) secs";
X    $recv = "<";
}
else {
X    $pat = "\\S+\\s+(\\S+)\\s+\\(([-0-9:/]+)\\)\\s+\\(\\d+\\)\\s+(\\w+) (\\d+) b (\\d+) secs";
X    $recv = "received";
}
X
%hosts = ();		# hosts seen
%bytes_in = ();		# of bytes received from host
%bytes_out = ();	# of bytes sent to host
%secs_in = ();		# of seconds connect for recving
%secs_out = ();		# of seconds connect for sending
%files_in = ();		# of input requests
%files_out = ();	# of output requests
X
# read info, break the lines and tally
X
while ( <STDIN> ) {
X  if ( /^$pat/o ) {
#   print "host $1, date $2, dir $3, bytes $4, secs $5.$6\n";
X    $6 = 0 if $type eq "U";
X    # gather timestamps
X    $last_date = $2;
X    $first_date = $last_date unless defined $first_date;
X
X    # initialize new hosts
X    unless ( defined $hosts{$1} ) {
X      $hosts{$1} = $files_in{$1} = $files_out{$1} = 
X	$bytes_in{$1} = $bytes_out{$1} =
X	  $secs_in{$1} = $secs_out{$1} = 0;
X    }
X
X    # tally
X    if ( $3 eq $recv ) {		# recv
X      $bytes_in{$1} += $4;
X      $files_in{$1}++;
X      $secs_in{$1} += $5 + $6/1000;
X    }
X    else {			# xmit
X      $bytes_out{$1} += $4;
X      $files_out{$1}++;
X      $secs_out{$1} += $5 + $6/1000;
X    }
X  }
X  else {
X    print STDERR "Possible garbage: $_";
X  }
}
X
@hosts = keys (%hosts);
die "No info found, stopped" if $#hosts < 0;
X
################ report section ################
X
$thishost = do gethostname();
$thishost = (defined $thishost) ? "on node $thishost" : "report";
X
format std_head =
@|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"UUCP traffic $thishost from $first_date to $last_date"
X
Remote   -----------K-Bytes----------- ----Hours---- --Avg CPS-- --Files--
X Host         Recv      Sent     Total   Recv   Sent  Recv  Sent Recv Sent
.
format std_out =
@<<<<<<< @>>>>>>>> @>>>>>>>> @>>>>>>>> @>>>>> @>>>>> @>>>> @>>>> @>>> @>>>
$Zhost,   $Zi_bytes, $Zo_bytes, $Zt_bytes, $Zi_hrs, $Zo_hrs, $Zi_acps, $Zo_acps, $Zi_count, $Zo_count
.
X
$^ = "std_head";
$~ = "std_out";
X
do print_dashes ();
X
reset "T";	       # reset totals
X
foreach $host (@hosts) {
X  do print_line ($host, $bytes_in{$host}, $bytes_out{$host},
X		 $secs_in{$host},  $secs_out{$host},
X		 $files_in{$host}, $files_out{$host});
X
}
X
do print_dashes ();
do print_line ("Total", $Ti_bytes, $To_bytes,
X	       $Ti_secs, $To_secs, $Ti_count, $To_count);
X
################ that's it ################
X
sub print_line {
X  reset "Z";		# reset print fields
X  local ($Zhost, 
X	 $Zi_bytes, $Zo_bytes, 
X	 $Zi_secs, $Zo_secs, 
X	 $Zi_count, $Zo_count) = @_;
X  $Ti_bytes += $Zi_bytes;
X  $To_bytes += $Zo_bytes;
X  $Zt_bytes = $Zi_bytes + $Zo_bytes;
X  $Tt_bytes += $Zt_bytes;
X  $Zi_acps = ($Zi_secs > 0) ? sprintf ("%.0f", $Zi_bytes/$Zi_secs) : "0";
X  $Zo_acps = ($Zo_secs > 0) ? sprintf ("%.0f", $Zo_bytes/$Zo_secs) : "0";
X  $Zi_bytes = sprintf ("%.1f", $Zi_bytes/1000);
X  $Zo_bytes = sprintf ("%.1f", $Zo_bytes/1000);
X  $Zt_bytes = sprintf ("%.1f", $Zt_bytes/1000);
X  $Zi_hrs = sprintf ("%.1f", $Zi_secs/3600);
X  $Zo_hrs = sprintf ("%.1f", $Zo_secs/3600);
X  $Ti_secs += $Zi_secs;
X  $To_secs += $Zo_secs;
X  $Ti_count += $Zi_count;
X  $To_count += $Zo_count;
X  write;
}
X
sub print_dashes {
X  $Zhost = $Zi_bytes = $Zo_bytes = $Zt_bytes =
X    $Zi_hrs = $Zo_hrs = $Zi_acps = $Zo_acps = $Zi_count = $Zo_count = 
X      "------------";
X  write;
X  # easy, isn't it?
}
X
################ missing ################
X
sub gethostname {
X  $ENV{"SHELL"} = "/bin/sh";
X  $try = `hostname 2>/dev/null`;
X  chop $try;
X  return $+ if $try =~ /^[-.\w]+$/;
X  $try = `uname -n 2>/dev/null`;
X  chop $try;
X  return $+ if $try =~ /^[-.\w]+$/;
X  $try = `uuname -l 2>/dev/null`;
X  chop $try;
X  return $+ if $try =~ /^[-.\w]+$/;
X  return undef;
}
X
################ verify perl version ################
X
# do verify_perl_version ( [ required , [ message ] ] )
X
sub verify_perl_version {
X  local ($version,$patchlevel) = $] =~ /(\d+.\d+).*\nPatch level: (\d+)/;
X  $version = $version * 1000 + $patchlevel;
X
X  # did the caller pass a required version?
X  if ( $#_ >= 0 ) {
X    local ($req, $msg, @req);
X    @req = split (//, $req = shift);
X    # if the request is valid - check it
X    if ( $#req == 3 && $req > $version ) {
X      if ( $#_ >= 0 ) {	# user supplied message
X	$msg = shift;
X      }
X      else {
X        $msg = "Sorry, this program requires perl " . $req[0] . "." . $req[1] .
X	        " patch level " . $req % 100 ." or later.\nStopped";
X      }
X      die $msg;
X    }
X  }
X  return $version;
}
SHAR_EOF
chmod 0444 uutraf.pl ||
echo 'restore of uutraf.pl failed'
Wc_c="`wc -c < 'uutraf.pl'`"
test 5454 -eq "$Wc_c" ||
	echo 'uutraf.pl: original size 5454, current size' "$Wc_c"
fi
exit 0
-- 
Johan Vromans				       jv@mh.nl via internet backbones
Multihouse Automatisering bv		       uucp: ..!{uunet,hp4nl}!mh.nl!jv
Doesburgweg 7, 2803 PL Gouda, The Netherlands  phone/fax: +31 1820 62911/62500
------------------------ "Arms are made for hugging" -------------------------

vince@bcsaic.UUCP (Vince Skahan) (04/18/91)

In article <1991Apr16.070654.15375@pronto.mh.nl> Johan Vromans <jv@mh.nl> writes:
>
>>  Has anybody written a program (Perl?) to parse UUCP log files, to
>> give an idea how much each UUCP connection's being used, and for how
>> long?
>

Here's a HDB UUCP report generator in sh and awk.... it should scream if you
run it through a2p and use split rather than awk-isms   



#------------------------- cut here --------------------------------
#!/bin/sh
 
STATS="/usr/spool/uucp/.Admin/xferstats"
TMP="/tmp/hdb.tmp"
cat $STATS | sort > $TMP			# sort by system then process

awk '{

#
# ------------ sample data for incoming information ------------
#
#dsinc!uucp M (11/9-7:37:59) (C,701,1) [sio1] <- 475 / 5.933 secs, 80 bytes/sec
#
# ----------- sample data for outgoing information --------------
#
#dsinc!bcs212 M (11/9-8:02:16) (C,828,1) [sio1] -> 341 / 0.450 secs, 757 bytes/sec
#
#-------------------------------------------------------------------

BEGIN{

# initialize NAME to nothing
   NAME=" "

# print header

   printf ("\n                        Summary of UUCP Statistics\n")
   printf ("\n                               Total     Incoming     Outgoing      Percent\n")
   printf ("                      Bytes  Bytes/sec   Bytes/sec    Bytes/sec     Outgoing\n")
   printf ("                      -----  ----------  ---------    ---------     --------\n")
}
    
# step through the data file
# outcoming data indicated by ->
# ingoing data indicated by <-
# find which system by /systemname/

# incoming
/<-/ {
     time_in = time_in + $9 
     bytes_in = bytes_in + $7
     total_intime = total_intime + $9
     total_inbytes = total_inbytes + $7
    }                          

#outgoing
/->/ {
     time_out = time_out + $9 
     bytes_out = bytes_out + $7
     total_outtime = total_outtime + $9
     total_outbytes = total_outbytes + $7
    }
 
{

 if  ( $1 != NAME ) 
  {  
    if ( NAME != " " ) 
      {
      printf ("%15s   %7d %7d %11d %11d %13d  \n",  NAME, host_bytes, host_rate, host_inrate, host_outrate, host_pct_out);
      }
      NAME = $1
      host_intime = 0
      host_inbytes = 0
      host_outtime = 0
      host_outbytes = 0
      host_time = 0
      host_bytes = 0
      host_inrate = 0
      host_outrate = 0
      host_pct_out = 0
  }
 if (( ( $1 == NAME ) || ( $1 == " " ) ))
   {                                             
    if ( $6 == "<-" ) {
        host_intime = host_intime + $9 
        host_inbytes = host_inbytes + $7 
        }
     else {
         host_outtime = host_outtime + $9 
         host_outbytes = host_outbytes + $7
         }

    host_time = host_intime + host_outtime
    host_bytes = host_inbytes + host_outbytes

    if ( host_time > 0 ) {
        host_rate = host_bytes/host_time
        }
    if ( host_intime > 0 ) {
        host_inrate = host_inbytes/host_intime
        }
     if ( host_outtime > 0 ) {
        host_outrate = host_outbytes/host_outtime
        }
     if (host_bytes > 0 ) {
        host_pct_out = host_outbytes * 100 / host_bytes
       }
    }
}
END {

# summarize, print the last guy, and print the totals pretty

printf ("%15s   %7d %7d %11d %11d %13d  \n",  NAME, host_bytes, host_rate, host_inrate, host_outrate, host_pct_out)

total_bytes = total_inbytes + total_outbytes
total_time = total_intime + total_outtime

if ( total_time > 0 ) {
    total_rate = total_bytes/total_time
    }
if ( total_intime > 0 ) {
    total_inrate = total_inbytes/total_intime
    }
if ( total_outtime > 0 ) {
    total_outrate = total_outbytes/total_outtime
    }

if (( (total_inbytes > 0 ) || ( total_outbytes > 0 ) ))
  {
  total_bytes = total_inbytes + total_outbytes
  total_time = total_intime + total_outtime
  total_pct_out = total_outbytes * 100 / total_bytes
  printf("\n")
  printf("          total   %7d %7d %11d %11d %13d \n",  total_bytes, total_rate, total_inrate, total_outrate, total_pct_out);
  printf("\n")
  }

}' $TMP

rm $TMP


-- 
Vince Skahan   vince@atc.boeing.com  ...uw-beaver!bcsaic!vince

(what is there in the construction of mobile homes that seems 
	to attract tornadoes ??? ) 

vince@bcsaic.UUCP (Vince Skahan) (04/20/91)

I've had a couple of requests for perl-versions of the HDB report
generator I posted the other day...

(there was a typo in the original awk one...there's an extra 
	"{" in there at the beginning of the awk...
	sorry 'bout that)

I've also included a sample data file to test on...

1. unshar this puppy
2. invoke by "sort < hdb-summ.dat | hdb-summ.pl"
3. let me know if you improve or drastically simplify this
4. enjoy...

					Vince

#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -s ./hdb_summ.pl`
then
cat > ./hdb_summ.pl << '\End\Of\Shar\'
#!/usr/local/bin/perl
#
# hdb_summ.pl
#
# this generates a report totalled on a system!user basis for HDB uucp
# (basically an edited a2p output of an old-awk original program)
#
# invoke by "sort < hdb-data-file | this_program.pl"
#
# ------------ sample data for incoming information ------------
#
#dsinc!uucp M (11/9-7:37:59) (C,701,1) [sio1] <- 475 / 5.933 secs, 80 bytes/sec
#
# ----------- sample data for outgoing information --------------
#
#dsinc!bcs212 M (11/9-8:02:16) (C,828,1) [sio1] -> 341 / 0.450 secs, 757 bytes/sec
#
#-------------------------------------------------------------------

# initialize NAME to nothing
$NAME = ' ';

# step through the data file
# outcoming data indicated by ->
# ingoing data indicated by <-
# find which system by /systemname/

# incoming

while (<>) {

    ($user,$Fld2,$start,$Fld4,$interface,$in_out,$bytes,$Fld8,$time) = split(' ', $_, 9999);

    #incoming
    if (/<-/) {
	$time_in = $time_in + $time;
	$bytes_in = $bytes_in + $bytes;
	$total_intime = $total_intime + $time;
	$total_inbytes = $total_inbytes + $bytes;
    }

    #outgoing
    if (/->/) {
	$time_out = $time_out + $time;
	$bytes_out = $bytes_out + $bytes;
	$total_outtime = $total_outtime + $time;
	$total_outbytes = $total_outbytes + $bytes;
    }

    if ($user ne $NAME) {
	if ($NAME ne ' ') {
		write;
	}
	$NAME = $user;
	$host_intime = 0;
	$host_inbytes = 0;
	$host_outtime = 0;
	$host_outbytes = 0;
	$host_time = 0;
	$host_bytes = 0;
	$host_inrate = 0;
	$host_outrate = 0;
	$host_pct_out = 0;
    }

    if ((($user eq $NAME) || ($user eq ' '))) {	
	if ($in_out eq '<-') {
	    $host_intime = $host_intime + $time;
	    $host_inbytes = $host_inbytes + $bytes;
	}
	else {
	    $host_outtime = $host_outtime + $time;
	    $host_outbytes = $host_outbytes + $bytes;
	}

	$host_time = $host_intime + $host_outtime;
	$host_bytes = $host_inbytes + $host_outbytes;

	if ($host_time > 0) {
	    $host_rate = $host_bytes / $host_time;
	}
	if ($host_intime > 0) {
	    $host_inrate = $host_inbytes / $host_intime;
	}
	if ($host_outtime > 0) {
	    $host_outrate = $host_outbytes / $host_outtime;
	}
	if ($host_bytes > 0) {
	    $host_pct_out = $host_outbytes * 100 / $host_bytes;
	}
    }
}

# summarize, print the last guy, and print the totals pretty

write;

$total_bytes = $total_inbytes + $total_outbytes;
$total_time = $total_intime + $total_outtime;

if ($total_time > 0) {
    $total_rate = $total_bytes / $total_time;
}
if ($total_intime > 0) {
    $total_inrate = $total_inbytes / $total_intime;
}
if ($total_outtime > 0) {
    $total_outrate = $total_outbytes / $total_outtime;
}

if ((($total_inbytes > 0) || ($total_outbytes > 0))) {
    $total_bytes = $total_inbytes + $total_outbytes;
    $total_time = $total_intime + $total_outtime;
    $total_pct_out = $total_outbytes * 100 / $total_bytes;

    $~ = "TOTALS";
    write;
}

format top =
                                  Summary of UUCP Statistics
                          Total              Incoming           Outgoing       Percent
                      Bytes  Bytes/sec   Bytes  Bytes/sec   Bytes  Bytes/sec   Outgoing
                      -----  ----------  ----   ---------   ----   ---------   --------
.

format =
@<<<<<<<<<<<        @>>>>>>>    @>>     @>>>>>>>   @>>   @>>>>>>>     @>>        @>>>
$NAME,           $host_bytes, $host_rate, $host_inbytes, $host_inrate, $host_outbytes, $host_outrate, $host_pct_out
.

format TOTALS =

                    @>>>>>>>    @>>     @>>>>>>>   @>>   @>>>>>>>     @>>        @>>>
                $total_bytes,$total_rate, $host_inbytes, $total_inrate, $total_outbytes,$total_outrate, $total_pct_out

.

\End\Of\Shar\
fi
if `test ! -s ./hdb_summ.dat`
then
cat > ./hdb_summ.dat << '\End\Of\Shar\'
system1!username M (12/5-17:06:02) (C,991,1) [tty000] <- 101292 / 462.083 secs, 219 bytes/sec
system1!username M (1/4-7:55:19) (C,1623,1) [tty000] -> 179 / 0.600 secs, 298 bytes/sec
system1!username M (1/4-8:24:53) (C,1670,1) [tty000] <- 21514 / 98.616 secs, 218 bytes/sec
system1!username M (1/4-8:29:42) (C,1679,1) [tty000] <- 18821 / 86.400 secs, 217 bytes/sec
system1!username M (1/4-8:32:38) (C,1689,1) [tty000] -> 189 / 0.650 secs, 290 bytes/sec
system1!username M (1/4-8:43:53) (C,1707,1) [tty000] <- 2341 / 11.066 secs, 211 bytes/sec
system3!username M (1/5-14:57:46) (C,2345,1) [tty000] <- 49824 / 247.333 secs, 201 bytes/sec
system1!username M (3/1-13:24:41) (C,526,1) [tty000] <- 112050 / 510.983 secs, 219 bytes/sec
system1!username M (3/2-1:05:48) (C,913,1) [tty000] <- 21514 / 22.800 secs, 943 bytes/sec
system2!username M (3/31-4:24:13) (C,2683,1) [tty000] <- 10343 / 47.683 secs, 216 bytes/sec
system2!username M (4/13-5:30:16) (C,7613,1) [tty000] <- 705099 / 3215.050 secs, 219 bytes/sec
\End\Of\Shar\
fi
exit
-- 
                         Vince Skahan   
 vince@atc.boeing.com                  ...uw-beaver!bcsaic!vince

(ensure your child's future... fire and prosecute striking teachers !)