Text File

news.utdallas.edu!tamsun.tamu.edu!cs.utexas.edu!zaphod.mps.ohio-state.edu!uwm.edu!ux1.cso.uiuc.edu!news.cso.uiuc.edu!ekatz Mon Mar 22 15:42:22 CST 1993 Article: 1519 of comp.infosystems.gopher Xref: feenix.metronet.com comp.infosystems.gopher:1519 alt.gopher:113 Newsgroups: comp.infosystems.gopher,alt.gopher Path: feenix.metronet.com!news.utdallas.edu!tamsun.tamu.edu!cs.utexas.edu!zaphod.mps.ohio-state.edu!uwm.edu!ux1.cso.uiuc.edu!news.cso.uiuc.edu!ekatz From: ekatz@ncsa.uiuc.edu (Eric Katz) #Subject: GopherReport v.2.0 Date: Mon, 22 Mar 1993 17:14:40 GMT Message-ID: <1993Mar22.171440.741@ncsa.uiuc.edu> Distribution: usa Sender: ekatz@ncsa.uiuc.edu (Eric Katz Originator: ekatz@landrew.ncsa.uiuc.edu Organization: Nat'l Ctr for Supercomp App (NCSA) @ University of Illinois Lines: 536

Following is the new release of GopherReport version 2.0. Thanks to all who have contributed comments and bug reports. There are 2 important items to remember with this new release.

1. invoking with now arguements now displays a help page. 2. This version corrects a bug that incorrectly calculated file/directory accesses. I apologize for any inconvenience this may have caused.

See the revision history in the program text for a summary of features and bug fixes.

<<<<< CUT HERE >>>>

#!/usr/local/bin/perl sub USAGE { print "USAGE: GopherReport -a|d|t|f|h|e [-s] [-vN] [-l logname] [keys] a All d Daily t Time f Files h Host e Errors s Summary l Name of the log file vN Verbosity D Current Day only\n"; print " keys To limit the report to specific days, times, files, and/or hosts. Any combination of keys may be specified. See examples below. Try to use the following conventions for the best results: Search for a date: 'nn' ie: 10 Search for a time: 'nn:' ie: 10: Search for a Day: 'Xxx' ie: Sun or Sunday Search for a file: 'xxx' ie: software or 'xx/' you may need a leading or '/xx' or trailing '/' Search for a domain: '.xxx' ie: .edu or ncsa\n\n"; exit; }

# Written by: Eric Katz # email: ekatz@ncsa.uiuc.edu # If you use this program regularly please send e-mail to the above # address and I will try to provide you with updated versions as they # come available. I am also interested in knowing how often you rotate # your gopher log and how long you keep old logs. ######################################################################### # Permission is granted to anyone to use this software for any purpose on # any computer, and to alter it for your personal use. Please do not # distribute any alterations. # # 0. This software is provided "as is" and without any express or implied # warranties, including, without limitation, the implied warranties of # merchantability and fitness for a particular purpose. # # 1. The author is not responsible for the consequences of the use of this # software, no matter how deleterious, even if they arise from flaws in it. # # 2. The origin of this software must not be misrepresented, either by # explicit claim or by omission. # # # 3. This software may not be sold. # # 4. This notice may not be removed or altered. # ######################################################################### # To install - Please remove everthing above the #! line. # Change the perl path to reflect the location of your perl installation. # Then answer the following question.

# Whereis your gopher log? = "/var/log/gopher_log";

###################################################################### # DO NOT CHANGE ANTHING BELOW THIS LINE FOR DISTRIBUTION. # You make may changes for your personal use but DO NO DISTRIBUTE YOUR # CHANGES. # # REVISION HISTORY # V1.0 Released 2/9/93 # V1.1 Released 2/15/93 # Bug Fix: File display now correctly displays file names with spaces # Bug Fix: Now handles file names with regexp in them. # Bug Fix: Illegal division by zero if no connections for the report # period fixed. # Bug Fix: Cleaned up output of large file names # Feature: Added number of files accessed. # Feature: Added varying level of verbosity to the output of file # accesses or host accesses. # In the case of file accesses the number represents the depth # of the directory tree that will be printed. # In other words -v1 will only report on root menu accesses, # while -v2 will go one directory deeper and so on. # In the case of host accesses, the number represents the # top percentile. # In other words, -v10 will show the top 10 percent of # connections. # Feature: Added -s, summary output. This prints only the total # number of connections and files accessed. # Feature: Added search key capability. Any arguments at the end of # the command line are assumed to be search key limiters. # It will try to 'do the right thing' but it is safer # to limit the type of search by using one of the -d, -t, # -f, or -h flags. # # # EXAMPLES: # GopherReport Thu Friday 10 11 14 15 Software # Will report on the number of people who # accessed the Software files on Thursday # and Friday during the 10am, 11am, 2pm, # and 4pm hours. # GopherReport -f edu # Will report on file accesses that have # the edu substring in them. # GopherReport -h edu # Will report on hosts with edu in the name. # GopherReport -fh edu # Will report on both hosts and files with # edu in them. # V2.0 Released 3/22/93 # # Bug Fix: Previous version incorrectly tallied bogus entries. # Bug Fix: Broke out directory accesses from file retrievals. # Feature: Added -l logname capability to examine logfiles other # than the default # Feature: Added -D to make it easier to examine the logfile for # today's information. # Feature: Added -e to scan for error messages ##########################################################################

require 'getopts.pl'; require 'ctime.pl';

# For now the only date information that is needed is the third field # regardless of whether it is a BSD system or not but we never know # what the future holds so I included the following subroutines. if (-e "/vmunix") { = "true"; } else { = "false"; }

# Get the current time and format it: =&ctime(time),"\n"; if ( eq "true") { (, , , , ) = split (" ",); } else { (, , , , , ) = split (" ",); }

&Getopts('adDtfhesl:v:');

# If no options are passed on the command line then display help page. &USAGE if (!() &! () &! () &! () &! () &! ());

# If an alternate logfile has been requested if (defined ) { = ; }

# If you want a printout for today only # = if (); if () { = "\\b" . . "\\b" . "|"; }

# If there are no search key limiters. if (($#ARGV < 0) &! ()) { = 1; = 1; = 1; = 1; }

# Else create the 'or' pattern matching string else { for (=0;<=$#ARGV;++) { if ([] =~ /Mon|Tue|Wed|Thu|Fri|Sat|Sun/) { = . [] . "|"; } elsif ([] =~ /\d+:/) { chop []; = . [] . "|"; } elsif ([] =~ /\d+/) { die "This does not make sense with the -D option\n" if (); = . "\\b" . [] . "\\b" . "|"; } else { = . [] . "|"; } } } if (defined ) { chop (); } else { = 1; } if (defined ) { chop (); } else { = 1; } if (defined ) { chop (); } else { = 1; } if (defined ) { chop ();

# We need to escape possible wildcard characters in this string, then # unescape the 'or' character =~ s/\W/\\$&/g; =~ s/\\\|/\|/g; } else { = 1; }

open (LOG,) || die "Couldn't open log file\n";

# Process the information in the log. # First, split the line into 2 parts separated by the colon. This tells # you who logged on and what they did. # Second, split the 'who' variable into the different components. # Third, split the 'what' variable into it's different components. # Fourth, If this is the first record in the log then set the start date # for the output to the date this entry was made. # Fifth, set the array information and determine the maximum value for # each array. The maximum value will be used to set the scale for the # the graph. # If the entry is that of a connection then increment the number # of connections, the number of connections for that weekday, # the number of connections for that hour of the day, and the # number of connections for that host. # If the entry is that of an action vs. a connection then increment # the number of retrievals for that directory. # Sixth, increment the record number.

= 1; while (<LOG>) { (, ) = split (/ : /,,2); (, , , , , , ) = split (/\s+/,); (, , ) = split (/\s+/,,3); chop ; (,,) = split (/:/,); if ( eq 1) { = " , @ "; } # This ridiculously long conditional just tries to do the right thing with # possible search key limiters if (() || ( || ( =~ //)) && ( || ( =~ //)) && ( || ( =~ //)) && ( || ( =~ (//) || ( =~ //)))) { if ( =~ /Connection/ ) { ++; {} ++; = {} if ({} > ); {} ++; = {} if ({} > ); {} ++; = {} if ({} > ); } elsif (( =~ /retrieved/) &! ( =~ /^0\./)) { if ( =~ /file/) { ++; {} ++; = {} if ({} > ); } if ( =~ /directory/) { ++; {} ++; = {} if ({} > ); }

} else { if ( =~ /not exist!!/) { = . "\n : "; = . " " if ( !~ /does/); ++; } else { if ( =~ /directory/) { = . " : \n"; ++; } } }

++; } } close LOG;

if () { print "==================================================================\n"; print " Gopher Error History\n"; print " Beginning \n"; print " Ending \n"; print "==================================================================\n"; print "\n"; print "NON-EXISTING FILES: Occurences\nDATE TIME FILE\n____________________________________________\n"; if () { print ; } print "\n\nNON-ACCESSIBLE DIRECTORIES: Occurences\nDATE TIME FILE\n____________________________________________\n"; if () { print ; } }

# Set the end date variable to that of the last entry in the log. = " , @ ";

if () { = 1; = 1; = 1; = 1; } # This number represents either the number of subdirectory levels to report # or the top x percentage of host connections depending on the context. if (defined ){ = ; } else { = 100; }

# Set an array to convert 3 letter weekday abbreviations to full names. @weekdays = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');

# Print the header print "\n\n"; print "==================================================================\n"; print " Gopher Usage Report\n"; print " Beginning \n"; print " Ending \n"; print "==================================================================\n"; print "\n"; print " Successful Failed\n"; print " ------------ ---------\n"; print "Total Number of Connections: \n"; print "Total Number of Files Retrieved: \n"; print "Total Number of Directories Accessed: \n"; print "\n"; exit if ();

if () { =0; # Print the connections/weekday data print "\n"; print "Connections Per Week Day\n";

printf ("%-8s%-30s\n%s\n"," Day","Connections","---------------------------------------------------------------------");

# Print the output for each record.

foreach (@weekdays) { # Convert the heading for each day (long form) into the short form for # accessing the array information. = substr(,0,3); # Calculate the number of stars to print. if ( > 0 ){ = '*' x ({} / * 50); } else { = ""; } # Print them. if (( =~ //) || ) { printf ("%-13s%3s %s\n",,{},); = + {}; } } print "\n"; print "Total for this Section: \n\n" if !(); }

if () { =0; # Iterate through the 'Hours' array to print the hourly information. The # first 10 numbers are quoted to preserve the leading 0. @Hours = ('00','01','02','03','04','05','06','07','08','09',10 .. 23); print "\n"; print "Connections Per Hour\n"; printf ("%-8s%-30s\n%s\n"," Hour","Connections","---------------------------------------------------------------------"); foreach (@Hours) { if ( > 0 ){ = '*' x ({} / * 50); } else { = ""; } if (( =~ //) || ) { = + {}; # Change the heading to read 'Midnight' if appropriate if ( == '00') { printf ("%-12s%4s %s\n","Midnight",{},); } # Change the heading to read 'Noon' if appropriate elsif ( == '12') { printf ("%-12s%4s %s\n","Noon",{},); } # Else just print the hour by number. else { printf ("%-12s%4s %s\n",,{},); } } } print "\n"; print "Total for this Section: \n\n" if !(); } if () { =0; print "\n"; print "Access Report for Directories and Files\n\n"; printf ("%s\n%s\n","Directory or File Accessed","-------------------------------------------------------------------------"); # Set an array of full pathnames @DIRS = keys(%Directory);

# Sort that array. @sortedDIRS = sort @DIRS;

foreach (@sortedDIRS) { # Calculate the number of stars for each entry (I add 1 just so that # each line gets at least 1 star for visual reasons. This actually sets # the scale off a bit but it is just meant to be a quick reference any # way. If you want more accurate graphing remove the '+ 1' in the following # line. # Calculate the number of stars to print.

# StringLength is used in order to split the filename into multiple # lines if it exceeds 30 characters. = 0; if ( > 0 ){ = '*' x (( {} / * 30) + 1); } else { = ""; } # Create an array consisting of the names in the full path without # the '/' @heading_format = split (/\//,);

= 1 if ( =~ //);

# Iterate through this list of file names that defines the path. For each # name in this path that is the same as the path of the previously printed # file name prepend a leading '.' to the name. # This is all to prevent the duplication of full pathnames in the output # to make it more readable.

for (=1; < $#heading_format;++) { if ([] eq []) { [] = "."; } else { [] = [] . "/"; }

= + length([]); if ( > 30){ [] = [] . "\n "; = 3; } }

# Pad the output to create nice columns. printf doesn't handle the # multiple line filenames very well. = " " x (37 - ( + length ([]))); [] = "[]";

# If this is the root menu then label it as such. if ( eq "\/") { @heading_format = "Main_Menu "; }

# Set the printed array element delimiter to null $" = "";

# Print it. if ( <= ) { if ( || ) { = + {}; printf ("%s%5s %s\n","@heading_format",{},); #printf ("%-35s%5s %s\n","@heading_format",{},); } }

# Set this to be the previously printed filename. @previous_heading = split (/\//,); = 0; } print "\n"; print "Total for this Section: \n\n" if !(); }

if () { =0;

# Print the name of each host and the number of time they connected. print "Connections per Host\n"; sub by_connections { {} <=> {}; } @HOSTS = keys(%Machines); @sortedHOSTS = sort by_connections @HOSTS; printf ("%-30s%s\n%s\n","Host ","Number of Connections","---------------------------------------------------------------------"); foreach (@sortedHOSTS) { if (( =~ //) || ) { if ( < ( * ()/100)){ = + {}; printf ("%-50s%s\n",,{}); } } } print "\n"; print "Total for this Section: \n\n" if !(); } --

=============================================== Eric Katz (ekatz@ncsa.uiuc.edu) Computer Utilization Analyst