[comp.mail.uucp] Log summaries

brendan@cs.widener.edu (Brendan Kehoe) (04/15/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?

Brendan
-- 
     Brendan Kehoe - Widener Sun Network Manager - brendan@cs.widener.edu
  Widener University in Chester, PA                A Bloody Sun-Dec War Zone
      "Does this person look relaxed to you?  Well, it's actually an
              experiment of Contour's new 565-E chair!"

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" -------------------------

chip@tct.com (Chip Salzenberg) (04/16/91)

According to brendan@cs.widener.edu (Brendan Kehoe):
>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?

Sure.  This one, "uuconstat", is for HDB UUCP.  Shar and enjoy.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  uuconstat
# Wrapped by chip@count on Tue Apr 16 12:51:17 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'uuconstat' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uuconstat'\"
else
echo shar: Extracting \"'uuconstat'\" \(3648 characters\)
sed "s/^X//" >'uuconstat' <<'END_OF_FILE'
Xeval 'exec /bin/perl -S $0 ${1+"$@"}'
X	if 0;
X
X# $Id: uuconstat,v 1.3 90/10/23 10:29:08 chip Exp Locker: chip $
X#
X# Print UUCP connect time statistics.
X#
X# $Log:	uuconstat,v $
X# Revision 1.3  90/10/23  10:29:08  chip
X# Don't count "wrong time" as a failure.
X# 
X# Revision 1.2  90/09/28  11:05:53  chip
X# Better function names and output format.
X# 
X# Revision 1.1  90/06/01  12:23:36  chip
X# Initial revision
X# 
X
X$LOGDIR = "/usr/spool/uucp/.Log/uucico";
X
X$verbose = 0;
X$debug = 0;
Xwhile (@ARGV) {
X	$_ = $ARGV[0];
X	last unless s/^-//;
X	shift;
X	last if $_ eq "-";
X	$verbose = 1 if s/v//g;
X	$debug = 1   if s/d//g;
X}
X
Xif (@ARGV == 0) {
X	opendir(LOG, $LOGDIR) || die "$LOGDIR: $!\n";
X	@ARGV = grep($_ ne "." && $_ ne "..", sort readdir(LOG));
X	closedir(LOG);
X}
X
Xformat top =
XUUCP Connect Time Statistics
X
XSystem      Succ  Fail  Tot Time  Avg Time
X----------  ----  ----  --------  --------
X.
X
Xformat STDOUT =
X@<<<<<<<<<  @>>>  @>>>   @>>>>>    @>>>>>
X$system, $success, $failure, $fmt_time, $fmt_avgtime
X.
X
Xformat SUMMARY =
X----------  ----  ----  --------  --------
XTotals      @>>>  @>>>   @>>>>>    @>>>>>
X        $t_success, $t_failure, $fmt_time, $fmt_avgtime
X.
X
Xforeach (@ARGV) {
X	$_ = $LOGDIR."/".$_ unless ($_ eq "-") || m#/#;
X}
X
Xwhile (<>) {
X	chop;
X	next unless s/^\S+\s+(\S+)[^(]+\(/$1 \(/;
X	($system, $dt, $what) = split(/\s+/, $_, 3);
X	$_ = $what;
X
X	@DT = &DT($dt);
X	unless (@DT == 5) {
X		print STDERR "warning: bad date/time at ", $.,
X				" in ", $system, "\n";
X		next;
X	}
X
X	$now = &CTIME(@DT);
X	if (!defined($first_time) || $now lt $first_time) {
X		$first_time = $now;
X	}
X	if (!defined($last_time) || $now gt $last_time) {
X		$last_time = $now;
X	}
X
X	$SYSTEMS{$system} = 1;
X	if (/SUCCEEDED.*call to/) {
X		if (@START && $verbose) {
X			print STDERR "warning: unterminated call to ",
X				$start_system, " at ", &CTIME(@START), "\n";
X		}
X		@START = @DT;
X		$start_system = $system;
X	}
X	elsif (/OK.*complete/
X	    || @START && (/CAUGHT.*sig/ || /INTREXIT/)) {
X		$call_began = &HMS_SECONDS(@START[2..4]);
X		$call_ended = &HMS_SECONDS(@DT[2..4]);
X		if ($call_ended < $call_began) {
X			$call_ended += &ONE_DAY;
X		}
X
X		if ($debug) {
X			print STDERR &CTIME(@START), " to ",
X				&CTIME(@DT), " makes ",
X				($call_ended - $call_began),
X				" seconds.\n";
X		}
X
X		$TIME{$system} += ($call_ended - $call_began);
X		++$SUCCESS{$system};
X		@START = ();
X	}
X	elsif (/WRONG TIME/) {
X		# do nothing
X	}
X	elsif (/CONN FAILED/ || /LOST LINE \(LOGIN\)/) {
X		++$FAILURE{$system};
X	}
X}
X
Xforeach $system (sort keys(%SYSTEMS)) {
X	$time = $TIME{$system};
X	$success = $SUCCESS{$system};
X	$failure = $FAILURE{$system};
X
X	$fmt_time = &FMT_SECONDS($time);
X	$fmt_avgtime = $success ? &FMT_SECONDS($time / $success) : "";
X	write;
X
X	$t_success += $success;
X	$t_failure += $failure;
X	$t_time += $time;
X}
X
Xif ($t_success || $t_failure) {
X	$fmt_time = &FMT_SECONDS($t_time);
X	$fmt_avgtime = $t_success ? &FMT_SECONDS($t_time / $t_success) : "";
X	$~ = "SUMMARY";
X	write;
X}
X
Xif ($first_time && $last_time) {
X	print "\n";
X	print "First attempt: $first_time\n";
X	print "Last attempt:  $last_time\n";
X}
X
Xexit;
X
Xsub DT {
X	local(@X);
X	@X = ($_[0] =~ m#^\((\d+)/(\d+)-(\d+):(\d+):(\d+),\d+,\d+\)#);
X	@X;
X}
X
Xsub HMS_SECONDS {
X	($hour, $minute, $second) = @_;
X
X	return ($hour * 3600) + ($minute * 60) + $second;
X}
X
Xsub ONE_DAY {
X	return 24 * 3600;
X}
X
Xsub FMT_SECONDS {
X	local($i) = @_;
X	local($h, $m, $s);
X
X	$s = $i % 60;
X	$i = int($i / 60);
X	$m = $i % 60;
X	$h = int($i / 60);
X	++$m if $s >= 30;
X	return sprintf("%2d:%02d", $h, $m);
X}
X
Xsub CTIME {
X	($month, $day, $hour, $minute, $second) = @_;
X
X	++$minute if ($second >= 30);
X	sprintf("%02d/%02d %02d:%02d", $month, $day, $hour, $minute);
X}
END_OF_FILE
if test 3648 -ne `wc -c <'uuconstat'`; then
    echo shar: \"'uuconstat'\" unpacked with wrong size!
fi
chmod +x 'uuconstat'
# end of 'uuconstat'
fi
echo shar: End of shell archive.
exit 0

-- 
Brand X Industries Custodial, Refurbishing and Containment Service:
         When You Never, Ever Want To See It Again [tm]
     Chip Salzenberg   <chip@tct.com>, <uunet!pdn!tct!chip>

bill@twg.bc.ca (Bill Irwin) (04/17/91)

chip@tct.com (Chip Salzenberg) writes:

} Sure.  This one, "uuconstat", is for HDB UUCP.  Shar and enjoy.

Do you have this in a /bin/sh flavour?  I don't have Perl.

} --
}      Chip Salzenberg   <chip@tct.com>, <uunet!pdn!tct!chip>
-- 
Bill Irwin    -       The Westrheim Group     -    Vancouver, BC, Canada
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
uunet!van-bc!twg!bill     (604) 431-9600 (voice) |     Your Computer  
bill@twg.bc.ca            (604) 430-4329 (fax)   |    Systems Partner

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 ??? ) 

ross@contact.uucp (Ross Ridge) (04/19/91)

chip@tct.com (Chip Salzenberg) writes:
>Sure.  This one, "uuconstat", is for HDB UUCP.  Shar and enjoy.

In article <1794@twg.bc.ca> bill@twg.bc.ca (Bill Irwin) writes:
>Do you have this in a /bin/sh flavour?  I don't have Perl.

Well since every one is posting their Perl scripts, I might as well
post my awk script. (This should work with old awk, but I've said that
before and been wrong.)  This works with HDB UUCP as well.

Basically you use it by saving the script in a file called uucpstats.awk
and run "awk -f uucpstats.awk /usr/spool/uucp/.Old/xferstats" after
after your uucp logs are cleaned out each night.

You get output like this:

--------------------------------------------------------------------------
                      Recieved                             Sent
Site       files    bytes     time    cps   files    bytes     time    cps
--------------------------------------------------------------------------
becker         6     3857     0:17    222      52   243533     5:34    728
birchmt        4     1235     0:12     97       3   634163  1:00:11    175
bkj386                                          6     5165     0:04   1237
dmntor        18    21949     1:27    251      28    76073     4:42    269
geac          16    49125     1:29    547      34   341543     8:11    694
jetpen         2      603     0:05    106  
mauxci         2     1679     0:06    269       4     3097     0:02   1277
nttor                                          28    46052     0:35   1312
robohack      16    38948     4:02    160      24    43608     3:48    190
spocom         2     2758     0:17    153      30    65609     6:09    177
tsltor                                         30    57721     0:46   1229
utdoe         98   911022    19:03    796      58    77013     1:04   1191
zooid          2      405     0:05     75       2     1064     0:06    171
--------------------------------------------------------------------------
 Totals:     166  1031581    27:08    633     299  1594641  1:31:00    291
--------------------------------------------------------------------------
                      Recieved                             Sent
tty        files    bytes     time    cps   files    bytes     time    cps
--------------------------------------------------------------------------
tty1A        158  1019461    25:48    658     282   930535    28:20    547
tty3A          6     3993     0:30    130      15   660394  1:02:39    175
tty3C          2     8127     0:48    166       2     3712     0:18    198
--------------------------------------------------------------------------

Total files: 465
Total bytes: 2626222
Total time:  1:58:26
Overall cps: 369

#
# uucpstats.awk -- by Ross Ridge (ross@contact.uucp) Public Domain
#
# $1       $2 $3   $4  $5    $6  $7   $8 $9   $10   $11 $12
# site!who C  date pid [tty] <-> size /  time secs, cps bytes/sec.

BEGIN	       {
		sitersize[""] = ""
		sitercount[""] = ""
		sitessize[""] = ""
		sitescount[""] = ""
		ttyrsize[""] = ""
		ttyrcount[""] = ""
		ttyssize[""] = ""
		ttyscount[""] = ""
	       }

	       {
		split($1, a, "!")
		site = a[1]
		tty = substr($5, 2, length($5) - 2)
		size = $7
		time = $9
# Fix for broken Xenix uucico:
#		time = $9 / 2

		sites[site] = site
		ttys[tty] = tty
	       }

$6 == "<-"     {
		sitersize[site] += size
		sitertime[site] += time
		sitercount[site]++
		ttyrsize[tty] += size
		ttyrtime[tty] += time
		ttyrcount[tty]++
		Rsize += size
		Rtime += time
		Rcount++
               }

$6 == "->"     {
		sitessize[site] += size
		sitestime[site] += time
		sitescount[site]++
		ttyssize[tty] += size
		ttystime[tty] += time
		ttyscount[tty]++
		Ssize += size
		Stime += time
		Scount++
               }
		
END	       {
		if (Scount + Rcount == 0) {
			print "empty log file"
			exit 1
		}
#
# Do a simple O(n^2) sort on the site names.
#
		for (i in sites) {
			highest = sites[i]
			for (j in sites)
				if (sites[j] > highest)
					highest = j
			s_sites[sitecount++] = highest
			sites[highest] = ""
		}
#
		for (i in ttys) {
			highest = ttys[i]
			for (j in ttys)
				if (ttys[j] > highest)
					highest = j
			s_ttys[ttycount++] = highest
			ttys[highest] = ""
		}
#		       12345678901234567890123456789012345678901234567890123456789012345678901234567890
		print "--------------------------------------------------------------------------"
		print "                      Recieved                             Sent"
		print "Site       files    bytes     time    cps   files    bytes     time    cps"
		print "--------------------------------------------------------------------------"
		while (sitecount) {
			s = s_sites[--sitecount]
			printf("%-8.8s  ", s)
			if (sitercount[s] == "")
				printf("                                 ")
			else {
				printf("%6d ", sitercount[s])
				printf("%8d ", sitersize[s])
				t = sitertime[s]
				if (t < 3600)
					printf("   %2d:%02d ", t / 60, t % 60)
				else
					printf("%2d:%02d:%02d ", t / 3600, (t / 60) % 60, t % 60)
				printf("%6d  ", sitersize[s] / t)
			}
			if (sitescount[s] == "")
				printf("\n")
			else {
				printf("%6d ", sitescount[s])
				printf("%8d ", sitessize[s])
				t = sitestime[s]
				if (t < 3600)
					printf("   %2d:%02d ", t / 60, t % 60)
				else
					printf("%2d:%02d:%02d ", t / 3600, (t / 60) % 60, t % 60)
				printf("%6d\n", sitessize[s] / t)
			}
		}
		print "--------------------------------------------------------------------------"
		printf(" Totals:  ")
		if (Rcount == "")
			printf("                                  ")
		else {
			printf("%6d ", Rcount)
			printf("%8d ", Rsize)
			if (Rtime < 3600)
				printf("   %2d:%02d ", Rtime / 60, Rtime % 60)
			else
				printf("%2d:%02d:%02d ", Rtime / 3600, (Rtime / 60) % 60, Rtime % 60)
			printf("%6d  ", Rsize / Rtime)
		}
		if (Scount == "")
			printf("\n")
		else {
			printf("%6d ", Scount)
			printf("%8d ", Ssize)
			if (Stime < 3600)
				printf("   %2d:%02d ", Stime / 60, Stime % 60)
			else
				printf("%2d:%02d:%02d ", Stime / 3600, (Stime / 60) % 60, stime % 60)
			printf("%6d\n", Ssize / Stime)
		}
		print "--------------------------------------------------------------------------"
		print "                      Recieved                             Sent"
		print "tty        files    bytes     time    cps   files    bytes     time    cps"
		print "--------------------------------------------------------------------------"
		while (ttycount) {
			s = s_ttys[--ttycount]
			printf("%-8.8s  ", s)
			if (ttyrcount[s] == "")
				printf("                                 ")
			else {
				printf("%6d ", ttyrcount[s])
				printf("%8d ", ttyrsize[s])
				t = ttyrtime[s]
				if (t < 3600)
					printf("   %2d:%02d ", t / 60, t % 60)
				else
					printf("%2d:%02d:%02d ", t / 3600, (t / 60) % 60, t % 60)
				printf("%6d  ", ttyrsize[s] / t)
			}
			if (ttyscount[s] == "")
				printf("\n")
			else {
				printf("%6d ", ttyscount[s])
				printf("%8d ", ttyssize[s])
				t = ttystime[s]
				if (t < 3600)
					printf("   %2d:%02d ", t / 60, t % 60)
				else
					printf("%2d:%02d:%02d ", t / 3600, (t / 60) % 60, t % 60)
				printf("%6d\n", ttyssize[s] / t)
			}
		}
		print "--------------------------------------------------------------------------"

		print
		printf("Total files: %d\n", Rcount + Scount); 
		printf("Total bytes: %d\n", Rsize + Ssize); 
		printf("Total time: ");
		t = Rtime + Stime;
		if (t < 3600)
			printf("%2d:%02d\n", t / 60, t % 60)
		else
			printf("%2d:%02d:%02d\n", t / 3600, (t / 60) % 60, t % 60)
		printf("Overall cps: %d\n", (Rsize + Ssize) / t);
		print
}
-- 
Ross Ridge								 //
"The Great HTMU"							[oo]
ross@contact.uucp							-()-
ross@watcsc.uwaterloo.ca						 //