Listing 3.
tally_hourly.pl
Lincoln D. Stein
"On-the-Fly Plots Made Easy"
The Perl Journal, Summer 1999
 
0  #!/usr/bin/perl -T

1  use strict;
2  use CGI qw(param header -no_debug);
3  use CGI::Carp qw(fatalsToBrowser);
4  $ENV{'PATH'} = '/bin:/usr/bin';  

5  use constant GNUPLOT  => '/usr/local/bin/gnuplot';
6  use constant LOGFILES => '/home/www/logs';
7  $| = 1;

8   # if REQUEST_METHOD is set, then we're a CGI script,
9   # so we get the logfile name with param() and generate
10  # the GIF image.
11  unless (@ARGV) {
12     my $logfile = param('file');
13     die "Bad log file name: $logfile\n"
14     unless $logfile =~ /^([a-zA-Z][\w.-]*)$/;
15     $logfile = LOGFILES . "/$1";
16     die "Can't open log file $logfile\n" unless -r $logfile;
17     generate_gif($logfile);
18  }
19  # otherwise we're running as a regular program, and we
20  # parse the log file for use by GNUPLOT
21  else {
22     generate_data();
23  }

24  # Make the GIF image (as a CGI script)
25  sub generate_gif {
26      my $logfile = shift;
27      print header('image/GIF">);
28      open (GP,"|".GNUPLOT) || die "Couldn't open GNUPLOT: $!";

29      while (<DATA>) {
30          print GP $_;
31      }
32      print GP "plot '< $0 $logfile'";
33      close GP;
34  }

35  # Generate the data for use by GNUPLOT
36  sub generate_data {
37      my %HITS;
38      while (<>) {
39          next unless 
                 m!\[\d+/\w+/\d{4}:(\d+):\d+:\d+ [\d+-]+\]!;
40          my $hour = $1;
41          $HITS{$hour}++;
42      }
43      foreach (sort {$a<=>$b} keys %HITS) {
44          print join("\t",$_,$HITS{$_}),"\n";
45      }
46  }

     _ _DATA_ _
     set terminal gif small size 640,480 interlace
     set border
     set boxwidth
     set nogrid
     set nokey
     set nolabel
     set data style boxes
     set noxzeroaxis
     set noyzeroaxis
     set tics out
     set xtics nomirror 0,1,23
     set ytics nomirror
     set xlabel "Hour" 0,0
     set xrange [ -0.75 : 23.75]
     set ylabel "Hits" 0,0