📄 ch14.htm
字号:
one for Apache logfiles, derive their base methods. It will be submitted to the author
of the <TT>Logfile</TT> module after some additional testing.</P>
<P>For now, just drop the <TT>GD_Logfile.pm</TT> file (from Listing 14.4) into the
<TT>Logfile</TT> directory in your <TT>@INC</TT>. You'll also need to have the GD
extension and the <TT>Logfile</TT> module installed, of course. The <TT>GD_Logfile</TT>
module uses the <TT>GD</TT> package to produce a GIF image of the graph corresponding
to data from the <TT>report()</TT> method from the <TT>Logfile</TT> class. The entire
module, including the <TT>graph()</TT> subroutine, looks like Listing 14.4.
<CENTER>
<H3><A NAME="Heading14"></A><FONT COLOR="#000077">Listing 14.4. GD_Logfile.pm.</FONT></H3>
</CENTER>
<PRE><FONT COLOR="#0066FF">package Logfile::GD_Logfile;
=head1 NAME
GD_Logfile - add a graphing feature the Logfile class, a single method to
allow bar graph generation of log data. Uses the GD module to produce the
graph.
=head1 SYNOPSYS
Logfile::GD_Logfile::graph($l,Group => File,
Sort => Records,
ImSize => [640,480],
Font => `gdSmallFont'
);
Where $l is a Logfile object, ImSize is the output image size, and Font is
a font from the GD module. All other parameters to the Logfile::report()
method may be included, but only one List variable may be passed in.
=head1 AUTHOR
Bill Middleton - wjm@best.com
=cut
use GD;
sub graph{
my $self = shift;
my %par = @_;
my $group = $self->group($par{Group});
my $sort = $par{Sort} || $group;
my $font = $par{Font};
my $rever = (($sort =~ /Date|Hour/) xor $par{Reverse});
my $list = $par{List};
my ($keys, $key, $val, %keys);
my $direction = ($rever)?'increasing':'decreasing';
my (@list, %absolute);
my (@sorted, $rec_total, $largest, $list_total);
my ($width, $ht, $color, $black, $white);
my ($im, $i, $inc);
my($top,$bottom,$left,$right);
my($color_inc,$title);
my($third,$fourth,$current);
# Instantiate a new GD image based on args or default
if(ref($par{ImSize})){
$im = new GD::Image(@{$par{ImSize}});
$right = $par{ImSize}->[0] - 30;
$top = $par{ImSize}->[1] - 30 ;
$left = $par{ImSize}->[0] / 2;
$bottom = $par{ImSize}->[1] /10;
}
else{ # defaults to 640x480
$im = new GD::Image(640,480); # default
$right = 610;
$top = 450;
$left = 320;
$bottom = 48;
}
# Set up a few basic colors and sizes
$width = $right - $left;
$ht = $top - $bottom ;
$white = $im->colorAllocate(255, 255, 255);
$black = $im->colorAllocate(0 , 0, 0);
$im->transparent($white);
# Graphs of this sort only make sense with single variable
if ($list) {
if (ref($list)) {
die "Sorry, graphs may have only one List variable\n"
}
} else {
$list = "Records";
}
# Sum things up
while (($key,$val) = each %{$self->{$group}}) {
$keys{$key} = $val->{$sort};
$rec_total+=1;
$list_total += $val->{$list};
}
(defined $par{Top}) and $rec_total = $par{Top};
# Graph outline
$im->line($left,$top,$right,$top,$black);
$im->line($left,$top,$left,$bottom,$black);
# Graph Title
$title = "Percentages of $list by $group";
$im->string(gdLargeFont,$left,10,$title,$black);
$title = "Total $list = $list_total";
$im->string(gdMediumBoldFont,$left,
($top + $bottom/4),$title,$black);
# $i will be our color increment variable for grayscale
$i = 200;
$color_inc = 100 / $rec_total;
$top = $bottom + ($ht / $rec_total);
# A couple of text layout variables
$fourth= (($ht / $rec_total) / 4);
$third = (($ht / $rec_total) / 3);
# Main loop iterates over items, draws the text field and
# rectangle representing the percentage of total for each
for $key ( sort
{&Logfile::Base::srt($rever, $keys{$a}, $keys{$b})}
keys %keys){
my $val = $self->{$group}->{$key};
next unless defined($val);
$color = $im->colorAllocate($i, $i, $i);
if ($key =~ /$;/) {
die "Sorry, graphs may have only one key\n";
}
$current = $top - $fourth * 3;
$im->string(&{$font},10,$current,$key,$black);
$title = sprintf("%s(%4.2f%%)",' ` x 5,
($val->{$list}/$list_total * 100));
$current = $top - $third;
$im->string(&{$font},10,$current,$title,$black);
$right = $left + ($width * $val->{$list} / $list_total);
$im->rectangle($left,$top,$right,$bottom,$black);
$im->fill(($left+1),($bottom+1),$color);
$bottom = $top;
$top += $ht / $rec_total;
last if defined $par{Top} && --$par{Top} <= 0;
$i -= $color_inc;
}
# Dump the GIF to stdout
print $im->gif;
}
1;
</FONT></PRE>
<P>Now you can produce a nice, two-dimensional graph of your log file data with Listing
14.5.
<CENTER>
<H3><A NAME="Heading15"></A><FONT COLOR="#000077">Listing 14.5. GD_Logfile.test.</FONT></H3>
</CENTER>
<PRE><FONT COLOR="#0066FF">#!/usr/bin/perl
require Logfile::Apache;
require GD_Logfile;
$l = new Logfile::Apache File => `apache-ncsa.log',
Group => [qw(Domain File )];
Logfile::GD_Logfile::graph($l,Group => File,
Sort => Records,
ImSize => [640,480],
Font => `gdSmallFont'
);
</FONT></PRE>
<P>This is then invoked as</P>
<PRE><FONT COLOR="#0066FF">perl GD_Logfile.test > output.gif
</FONT></PRE>
<P>Using the sample Apache access log file provided with the <TT>Logfile</TT> module,
called <TT>apache-ncsa.log</TT>, the resulting graph is output to the <TT>output.gif</TT>
file and looks like Figure 14.1.</P>
<P>That pretty much wraps up our discussion regarding HTTP log files. It's worth
mentioning, however, that you also can use the statistics packages that are available,
with some modifications, to summarize the data in a log file. Check your nearest
CPAN archive and the Modules List for these statistics modules. <TT><BR>
<BR>
<B>Figure 14.1.</B> </TT>Graphical representation of log file data.
<CENTER>
<H4><A NAME="Heading16"></A><FONT COLOR="#000077">Converting Existing Documentation
to HTML</FONT></H4>
</CENTER>
<P>Another one of the many tasks that the Webmaster may be called upon to perform
is to make existing documentation available via the Web. Of course, by configuring
the server properly, you can specify a MIME typing to invoke the appropriate application
or plug-in on the client to allow the client to view the document. Sometimes, though,
it's preferable to actually convert the document into an HTML document and serve
it up in the natural way. Using Perl, it's relatively easy to convert any given document
to an HTML representation, as long as you know the general layout of the document
and have a mapping from the document's internal layout to a corresponding HTML element.
<B><TT>General Issues</TT></B> As we've stated, the general algorithm for converting
a given document to HTML implies knowing something about the internals of the document.
For ASCII text files, this is fairly easy to do. Binary formats require some additional
investigation. Furthermore, some types of binary document formats are proprietary
and may require that you obtain the structure from the owner or distributor in order
to parse them properly. For the sake of brevity, we'll restrict our discussion to
parsing and converting ordinary ASCII documents to HTML. <B><TT>Mail Folders</TT></B>
The typical UNIX mail file is one example of a text file that has a known format
and that's relatively easy to parse and convert to an HTML equivalent. The resulting
HTML file may be as useful as a Web document when it contains the messages sent to
a public mailing list, for instance. There are numerous means available for making
a mail file searchable. Some searching algorithms have already been discussed in
this book; however, because we know the format of a mail file, we not only can search
through it more easily, but we also can provide a hypertext view of the messages
within. Converting a mail file to an HTML document provides the ability to browse
all of the me
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -