Click Here!
home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Perl CGl Programming: No experience required.
(Publisher: Sybex, Inc.)
Author(s): Erik Strom
ISBN: 0782121578
Publication Date: 11/01/97

Bookmark It

Search this book:
 
Previous Table of Contents Next


Enter the following code in your text editor, ensuring that the file and path names defined at the top match valid names on your system:

   #!perl/bin/perl

   # hitcnt.pl
   #
   # First version. Goes through a single IIS log file, tallying
   # the hits and IP addresses from which they came.
   # Command-line version — output to screen.

   # Define path to a single log file.

       $LogDir = "c:/winnt/system32/logfiles/";
       $LogFile = "in970502.log";
       $LogPath = $LogDir.$LogFile;

   # Attempt to open the log file; die if it doesn’t happen.

       open (LOG, $LogPath) || die "Can’t open $LogPath: $!\n";

   # Loop through the log file a line at a time and extract
   # the entry information.

       $n = 0;               # Initialize a counter.

       while (<LOG>){
           ($ClientIP, $Dummy, $Date, $Time, $SvcName, $SrvrName, $SrvrIP,
               $CPUTime, $BytesRecv, $BytesSent, $SvcStatus, $NTStatus,
               $Operation, $Target, $Dummy) = split (/,/);

       # Store the client IP address, increment counter.

           $IPArray[$n] = $ClientIP;
           $n++;
           }                   # end while (<LOG>)

        close (LOG);            # Close the log file.

   # Store the total hits, then initialize two arrays for the IPs
   # and the number of hits for each.

       $TotalHits = $n;
       @IPHits = ();
       @NumHits = ();
       $HitCount = 0;

   # Loop through @IPArray and sort out the IPs that match,
   # incrementing that IPs hit count for each match.

       for ($n = 0, $i = 0; $n < $TotalHits; $n++)
           {
           for ($p = 0; $p < $HitCount; $p++)
               {
               if ($IPArray[$n] eq $IPHits[$p])
                   {
                   $NumHits[$p]++;
                   last;                   # Same as break in C
                   }
               }

      # If $p == $HitCount, no matches were found. This is a new
      # IP address, so add it to the list.
        if ($p == $HitCount)
            {
            $IPHits[$HitCount] = $IPArray[$n];
            $NumHits[$HitCount]++;
            $HitCount++;
            }
        }        # end for ($n = 0...)

   # Print out the results.

       print "On 05/02/97:\n\n";

       for ($n = 0; $n < $HitCount; $n++)
           {
           print "$IPHits[$n] registered $NumHits[$n] hits\n";
           }

   #                    End hitcnt.pl

Save this Perl script as hitcnt.pl and run it from the command line. Output similar to that illustrated in Figure 9.7 will be written to the screen.


Figure 9.7:  The hits on the Web site are tallied and written to the screen.

Analyzing the First Hit Counter

The first version of hitcnt.pl is ugly in its output—as are most command-line applications—but you have built the foundation for something much bigger.


TIP:  Sambar server users need to make only two small changes to get hitcnt.pl to work with their log files. First, of course, change the log file locations defined at the top of the program. Then change the line that calls Perl’s split function to the same call in logs1.pl, the script you wrote in the previous section.

The only new Perl construct presented in hitcnt.pl is the last statement, which will be covered shortly. The script presents some slightly knotty logical concepts, though, and they might be easier to understand if we step through the logic in English:

1.  Pick up the IP address from every entry in the log file. Store all of them in an array.
2.  Define two empty arrays: one to hold individual IP addresses and the other to hold the number of times a particular IP appeared in the log file.
3.  Set up two loops: one to go through the first array of IPs from the log file entries and another to go through the second array of individual IPs.
4.  Check each IP in the first array against the members of the second. If the two match, increment the hit count for that member of the second array. If no matches occur, this is a new IP—add it to the second array.
5.  Print them out.

The client IP addresses are picked up from the log file in the same way you did it in the previous section. Notice that we didn’t change the call to split:

   while (<LOG>)
           {
           ($ClientIP, $Dummy, $Date, $Time, $SvcName, $SrvrName, $SrvrIP,
               $CPUTime, $BytesRecv, $BytesSent, $SvcStatus, $NTStatus,
               $Operation, $Target, $Dummy) = split (/,/);

There is one exception, however. Rather than storing the input line in a local variable, we have allowed split to take its data directly from the standard input, defined in Perl, you’ll recall, as $_. This is why split has only its search pattern as a parameter.


NOTE:  There is no reason to call split with the full list of variables for an entire log file entry because only the first variable is used in hitcnt.pl. However, you probably will want more than just an IP address in future versions of the script, so you might as well leave the rest of the variables there.

The next code section stores the total number of entries in the log file and initializes a couple of empty arrays:

   # Store the total hits, then initialize two arrays for the IPs
   # and the number of hits for each.

       $TotalHits = $n;
       @IPHits = ();
       @NumHits = ();
       $HitCount = 0;

The variable $HitCount will be used to store the number of individual IP addresses—that is, unique IPs—that will be picked out of the full array of entries.

Now the two loops are set up to pick out the individual IPs and keep track of the number of times they’ve hit.

   # Loop through @IPArray and sort out the IPs that match,
   # incrementing that IPs hit count for each match.

       for ($n = 0; $n < $TotalHits; $n++)
           {
           for ($p = 0; $p < $HitCount; $p++)
               {
               if ($IPArray[$n] eq $IPHits[$p])
                   {
                   $NumHits[$p]++;
                   last;                   # Same as break in C
                   }
               }

       # If $p == $HitCount, no matches were found.  This is a new
       # IP address, so add it to the list.

           if ($p == $HitCount)
               {
               $IPHits[$HitCount] = $IPArray[$n];
               $NumHits[$HitCount]++;
               $HitCount++;
               }
           }        # end for ($n = 0...)


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited.