home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2000 February
/
PCWorld_2000-02_cd.bin
/
live
/
usr
/
X11R6
/
lib
/
X11
/
procmeter
/
logtail
next >
Wrap
Text File
|
1998-10-13
|
4KB
|
133 lines
#!/usr/bin/perl
# copyright: Joey Hess 1997 GPL.
die q{
Logtail watches one or more log files, and makes procmeter display graphs of
how many lines are added to each file.
Syntax:
logtail filespec , [filespec , ... ] fifo
fifo Basename of the fifo file to use to communicate with
procmeter. The fifo.dat and fifo.def files will be created
on the fly.
filespec Specifies a file to watch and options for this file.
Filespec Format:
file=f units=u size=s pattern=p average=n rotate=[yes|no]
file Watch the file specified. A required part of each
filespec. This item is required.
units The units to use (default: "lines")
size How many lines in this file it takes to make one
line on the graph (default: 1)
name Name of this item on the graph (default: basename of file)
pattern Pattern that the line must match to be counted. See perlre(1).
(default: none specified, which matches everything)
Note that if pattern contains a () grouping, then the
value of that grouping is used for the value of the line.
Useful for doing something like displayng stats on how many K
are being transfered from your web server.
rotate If "yes", try to figure out when the file is rotated, and
recover from that condition. (default: yes)
Example:
logtail file=/var/log/httpd/access_log units=hits size=10 , \
file=/var/log/messages rotate=yes size=2 \
/tmp/logfifo
} unless @ARGV;
$fifo_basename=pop(@ARGV);
$fifo="$fifo_basename.dat";
system 'mkfifo',$fifo; # perl has no mkfifo command.
open (DEF,">$fifo_basename.def") ||
die "open $fifo.def failed: $!\n";
my %filespec;
my $spec_counter=0;
foreach $word (@ARGV) {
if ($word eq ',') {
SaveFileSpec(%filespec);
undef %filespec;
}
elsif ($word=~/(.*?)=(.*)/ ne undef) {
$filespec{$1}=$2;
}
else {
die "Unknown item found in filespec: $word\n";
}
}
SaveFileSpec(%filespec);
undef %filespec;
close DEF;
# Saves a filespec into global data hashes.
sub SaveFileSpec { my %filespec=@_;
my $filespec=$spec_counter++;
if (!$filespec{file}) {
die "Filespec does not contain file name.\n";
}
if (!$filespec{size}) {
$filespec{size}=1;
}
if (!$filespec{name}) {
($filespec{name})=$filespec{file}=~m:.*/(.*?)$:;
}
if (!$filespec{units}) {
$filespec{units}='lines';
}
if ($filespec{pattern}) {
$log_pattern{$filespec}=$filespec{pattern};
}
open ($filespec,"<$filespec{file}")
|| die "open $filespec{file} failed: $!\n";
seek($filespec,0,2); # seek to eof.
$log_counter{$filespec}=0;
$log_filesize{$filespec}=-s $filspec{name};
$log_filename{$filespec}=$filespec{file};
print DEF "$filespec{name} $filespec{units} " .
$filespec{size} . "\n";
if ($filespec{rotate} eq 'yes') {
$rotate_protect{$filespec}=1;
}
}
for (;;) {
foreach $filespec (keys %log_counter) {
if ($rotate_protect && -r $log_filename{$filespec}) {
if (-s $log_filename{$filespec} < $log_filesize{$filespec}) {
# File size has decreased, assume the file has been
# rotated on us.
close $filespec;
open ($filespec,"<$log_filename{$filespec}");
seek($filespec,0,2); # seek to eof.
}
$log_filesize{$filespec}=-s $log_filename{$filespec};
}
while (!eof($filespec)) {
$_=<$filespec>;
if (! $log_pattern{$filespec} ||
m/$log_pattern{$filespec}/ ne undef) {
if ($1) {
$log_counter{$filespec} += $1;
}
else {
$log_counter{$filespec} += 1;
}
}
}
}
open (OUT,">$fifo") || die;
foreach $filespec (keys %log_counter) {
print OUT "$log_counter{$filespec}\n";
$log_counter{$filespec}=0;
}
close OUT;
select(undef,undef,undef,0.25); # why is this needed?
}