home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / countv01.zip / countHTTP.cmd next >
OS/2 REXX Batch file  |  1997-12-11  |  9KB  |  247 lines

  1. extproc perl -x -S
  2. #!/usr/bin/perl
  3.  
  4. # Parse PowerWeb HTTP log and calculate server statistics.
  5. #
  6. # countHTTP   Version 0.1  [10/12/1997]
  7. #
  8. # Copyright (C) 1997 by Ivan Adzhubei
  9. #
  10. # Web address:        http://www.protein.bio.msu.su/
  11. # Send comments to:    ivan@protein.bio.msu.su
  12.  
  13. # Month numbers
  14. %monthNum = (
  15.   Jan => '01',
  16.   Feb => '02',
  17.   Mar => '03',
  18.   Apr => '04',
  19.   May => '05',
  20.   Jun => '06',
  21.   Jul => '07',
  22.   Aug => '08',
  23.   Sep => '09',
  24.   Oct => '10',
  25.   Nov => '11',
  26.   Dec => '12',
  27. );
  28.  
  29. # A few defaults
  30. $logFile    = '/powerweb/logs/HTTP.log';
  31. $localIP    = '127.0.0.1';
  32. $localHost  = 'localhost';
  33.  
  34. # These are IP address range and domain name for the client requests which are
  35. # excluded from all statistics calculations. Usefull to exclude your own hosts
  36. # (producing lots of requests from your attempts to test/configure PW) from
  37. # countHTTP results. Configurable via command line options -en/-ed, but you may
  38. # place defaults for your net right here in the code to avoid typing excessively
  39. # long command line each time you start countHTTP.
  40. #
  41. # *** UNCOMMENT AND EDIT THE TWO LINES BELOW ***
  42. #
  43. #$myNetwork  = '111.222.333';
  44. #$myDomain   = 'mydomain.name.com';
  45.  
  46. # Parse command line options
  47. while (($arg = shift @ARGV) && $arg =~ /^-/) {
  48.   &printUsage,        exit if $arg =~ /^-(\?|h(elp)?)$/;
  49.   $logFile     = $1,    next if $arg =~ /^-f(.+)/;
  50.   $myNetwork   = $1,    next if $arg =~ /^-en(.+)?/;
  51.   $myDomain    = $1,    next if $arg =~ /^-ed(.+)?/;
  52.   $resolveName = 1,    if $arg =~ /n/;
  53.   $printLoad   = 1,    if $arg =~ /l/;
  54.   $printDocs   = 1,    if $arg =~ /d/;
  55.   $printClients= 1,    if $arg =~ /c/;
  56.   $strictHTML  = 1,    if $arg =~ /s/;
  57.   $printTotals = 1,    if $arg =~ /t/;
  58.   # Stop on -<date>, since we assume this is an ending date parameter.
  59.   last if $arg =~ /^-\d+\/\d+\/\d+$/;
  60. }
  61.  
  62. # Next arg is date range?
  63. $arg =~ /^(\d+\/\d+\/\d+)?-(\d+\/\d+\/\d+)?$/;
  64.  
  65. # Yes, argument looks like a date range
  66. if ($1 || $2) {
  67.   $firstDate = $1; $lastDate = $2;
  68.   if ($firstDate) {
  69.     $firstDate =~ /(\d+)\/(\d+)\/(\d+)/;
  70.     $firstYear = $3 + 0; $firstMonth = $2 + 0; $firstDay = $1 + 0;
  71.     die "Illegal starting date format\n" if $firstMonth < 1 || $firstMonth > 12 ||
  72.         $firstDay < 1 || $firstDay > 31;
  73.     $packedFirst = $firstYear * 12 * 31 + ($firstMonth - 1) * 31 + $firstDay - 1;
  74.   }
  75.   if ($lastDate) {
  76.     $lastDate =~ /(\d+)\/(\d+)\/(\d+)/;
  77.     $lastYear = $3 + 0; $lastMonth = $2 + 0; $lastDay = $1 + 0;
  78.     die "Illegal ending date format\n" if $lastMonth < 1 || $lastMonth > 12 ||
  79.         $lastDay < 1 || $lastDay > 31;
  80.     $packedLast  = $lastYear  * 12 * 31 + ($lastMonth  - 1) * 31 + $lastDay  - 1
  81.   }
  82.   $arg = '';
  83. }
  84.  
  85. $arg = shift @ARGV if @ARGV;
  86.  
  87. open(LOG,$logFile) || die "Can't open file \"$logFile\"\n";
  88.  
  89. while (<LOG>) {
  90.   chomp;
  91.   next if /^\s*$/;
  92.  
  93.   /^(\S+)\s+(\S+)\s+(\S+)\s+\[(.+?)\]\s+"(.+?)"/;
  94.   $client = $1; $server = $2; $auth = $3; $datetime = $4; $request = $5;
  95.   print STDERR "WARNING! - Malformed log line:\n$_\n"
  96.       unless $client && $server && $auth && $datetime && $request;
  97.  
  98.   $request =~ /^\w+\s+(\S+)/; $document = $1;
  99.   $datetime =~ /^(\d+\/\w+\/\d+):([\d:]+)/; $date = $1; $time = $2;
  100.   $date =~ s/\/(\w+)\//\/$monthNum{$1}\//;
  101.   $date =~ /^(\d\d)\/(\d\d)\/(\d\d\d\d)/; $day = $1; $month = $2; $year = $3;
  102.   $day += 0; $month += 0; $year += 0;
  103.   $time =~ /^(\d\d):\d\d:\d\d/; $hour = $1 + 0;
  104.  
  105.   $firstLog = $date unless $firstLog;
  106.  
  107.   next if $client =~ /^$localIP/   || $client =~ /^$localHost$/;
  108.   next if ($myNetwork && $client =~ /^$myNetwork/) ||
  109.           ($myDomain  && $client =~ /$myDomain$/i);
  110.  
  111.   next if $strictHTML && $document !~ /^[^$&?=]*?\/(\w+(\.htm(l)?)?)?$/i;
  112.   next if $strictHTML && $document =~ /\/(cgi-bin|perl-bin|rexx-bin)\//i;
  113.  
  114.   $packedDate  = $year * 12 * 31 + ($month - 1) * 31 + $day - 1
  115.       if $firstDate || $lastDate;
  116.  
  117.   next if ($firstDate && $packedDate < $packedFirst) ||
  118.           ($lastDate  && $packedDate > $packedLast);
  119.  
  120.   next if $arg && $document !~ /$arg/i;
  121.  
  122.   $totalRequests{$document}{$client}++;
  123.   $totalLoad{$year}{$month}{$day}{$hour}++;
  124.  
  125. }
  126.  
  127. close(LOG);
  128.  
  129. print STDERR "Resolving client names" if $resolveName;
  130. foreach $document (keys %totalRequests) {
  131.   foreach $client (keys %{$totalRequests{$document}}) {
  132.     print STDERR '.' if $resolveName;
  133.     $clientName{$client} = '';
  134.     unless (!$resolveName || $clientName{$client}) {
  135.       $cliName = '';
  136.       @lookupResults = `nslookup $client 2>nul`;
  137.       foreach $line (@lookupResults) {
  138.         chomp($line);
  139.         $cliName = $1 if $line =~ /^Name:\s+(\S+)/;
  140.       }
  141.       $clientName{$client} = $cliName if $cliName;
  142.     }
  143.     $documentCount{$document} += $totalRequests{$document}{$client};
  144.     $clientName{$client} = $client unless $clientName{$client};
  145.     $clientCount{$clientName{$client}} += $totalRequests{$document}{$client};
  146.     $totRequests += $totalRequests{$document}{$client};
  147.   }
  148. }
  149. print STDERR "\n" if $resolveName;
  150.  
  151. if ($printDocs) {
  152.   foreach $document (sort {$documentCount{$b}<=>$documentCount{$a}} keys %documentCount) {
  153.     print "$document:\n" if $printDocs;
  154.     unless ($printTotals) {
  155.       foreach $client (sort {$totalRequests{$document}{$b}<=>$totalRequests{$document}{$a}} keys %{$totalRequests{$document}}) {
  156.         printf "  %-36s%5s\n", $clientName{$client}, "($totalRequests{$document}{$client})";
  157.       }
  158.     }
  159.     printf "  Subtotal:%32s\n", "($documentCount{$document})";
  160.   }
  161. }
  162.  
  163. if ($printClients) {
  164.   foreach $client (sort {$clientCount{$b}<=>$clientCount{$a}} keys %clientCount) {
  165.     printf "%-36s%5s\n", $client, "($clientCount{$client})";
  166.   }
  167. }
  168.  
  169. $firstDate = $firstLog unless $firstDate;
  170. $lastDate  = $date     unless $lastDate;
  171.  
  172. print "\n------\nTotal ", $strictHTML ? 'HTML ' : '', "requests $firstDate - $lastDate";
  173. print " for '$arg'" if $arg;
  174. print ": $totRequests\n";
  175.  
  176. exit unless $printLoad;
  177.  
  178. foreach $year (sort keys %totalLoad) {
  179.   foreach $month (sort keys %{$totalLoad{$year}}) {
  180.     foreach $day (sort keys %{$totalLoad{$year}{$month}}) {
  181.       foreach $hour (sort keys %{$totalLoad{$year}{$month}{$day}}) {
  182.         $monthLoad{$year}{$month} += $totalLoad{$year}{$month}{$day}{$hour};
  183.         $hourLoad{$hour} += $totalLoad{$year}{$month}{$day}{$hour};
  184.         $hourList{$hour}++;
  185.       }
  186.     }
  187.   }
  188. }
  189.  
  190. for $hour (0..23) {
  191.   $hourList{$hour}++ unless $hourList{$hour};
  192.   $aveLoad = $hourLoad{$hour} / $hourList{$hour};
  193.   $maxLoad = $aveLoad > $maxLoad ? $aveLoad : $maxLoad;
  194.   $totLoad += $aveLoad;
  195.   push @averageLoad, $aveLoad;
  196. }
  197.  
  198. $maxLoad = $maxLoad / $totLoad * 100;
  199.  
  200. print "\n------\nServer daily load (percent/hour):\n\n";
  201. for ($percent=int($maxLoad+0.5); $percent>0; $percent--) {
  202.   printf("%5s",($percent % 5) ? '|' : "$percent-|");
  203.   for $hour (0..23) {
  204.     $percentLoad = $averageLoad[$hour] / $totLoad * 100;
  205.     print (int($percentLoad+0.5) >= $percent ? '*' : '.');
  206.   }
  207.   print "\n";
  208. }
  209. print "  0-|", '-' x 24, "\n";
  210. print "     |  |  |  |  |  |  |  |\n";
  211. print "     0  3  6  9 12 15 18 21\n";
  212.  
  213. print "\n------\nServer load profile (hits/month):\n\n";
  214. foreach $year (sort {$a<=>$b} keys %monthLoad) {
  215.   foreach $month (sort {$a<=>$b} keys %{$monthLoad{$year}}) {
  216.     printf "%d/%02d:%8d\n", $year, $month, $monthLoad{$year}{$month};
  217.   }
  218. }
  219.  
  220. sub printUsage {
  221. print <<EOT
  222. countHTTP for PowerWeb++ Server                       Version 0.1  [10/12/1997]
  223.  
  224. usage: countHTTP [options] [date_range] [tag_regexp]
  225.   [date_range] is in form: dd/mm/yyyy-dd/mm/yyyy, either start or end date
  226.             is optional, but '-' separator is mandatory;
  227.   [tag_regexp] is Perl style regular expression, only matching documents are
  228.             counted; must be protected from shell in usual way (eg. quoted).
  229.   [options] are from among:
  230.   -h(elp)   show (this) help screen; -? also works.
  231.   -s        strict HTML mode, only requests ending in .htm(l) are counted,
  232.             form GET/POST's, requests for graphics, etc., are ignored.
  233.   -flogFile specify log file name (inc. path); default is to open HTTP.log
  234.             in /powerweb/logs dir on the current drive.
  235.   -enNET_IP exclude NET_IP range (eg. 111.222.333) from all statistics.
  236.   -edDOMAIN exclude DOMAIN name (eg. mydomain.com) from all statistics;
  237.             set both -e options to your own net/domain to exclude all of your
  238.             own testing/configuration requests to server from statistics.
  239.   -n        resolve and print client names instead of IP addresses; may take
  240.             really LONG time for large log files with many requests.
  241.   -l        print server load statistics: average daily and per month.
  242.   -d        print document requests statistics: document hits per client.
  243.   -c        print client statistics: total hits per each client.
  244.   -t        print only totals/subtotals, less detailed output.
  245. EOT
  246. }
  247.