#!/usr/bin/perl -w # # $Id: eet.pl,v 1.15 2003/01/13 05:28:42 jmates Exp $ # # Copyright (c) 2001-2002, Jeremy Mates. This script is free # software; you can redistribute it and/or modify it under the same # terms as Perl itself. # # Run perldoc(1) on this file for additional documentation. # ###################################################################### # # REQUIREMENTS require 5; use strict; ###################################################################### # # MODULES use Carp; # better error reporting use Getopt::Std; # command line option processing use File::Tail 0.91; # tail -f on steroids ###################################################################### # # VARIABLES my $VERSION; ($VERSION = '$Revision: 1.15 $ ') =~ s/[^0-9.]//g; my (%opts, @files, $prefix); # various File::Tail object preferences. listen much faster than default # to emulate tail(1) at expense of more busy wait. my $maxinterval = 2; my $interval = 1; my $adjustafter = 1; my $tail = 0; my $reset_tail = -1; ###################################################################### # # MAIN # parse command-line options getopts('h?m:i:a:t:r:f', \%opts); help() if exists $opts{'h'} or exists $opts{'?'}; $maxinterval = $opts{'m'} if exists $opts{'m'} and $opts{'m'} =~ /^\d+$/; $interval = $opts{'i'} if exists $opts{'i'} and $opts{'i'} =~ /^\d+$/; $adjustafter = $opts{'a'} if exists $opts{'a'} and $opts{'a'} =~ /^\d+$/; $tail = $opts{'t'} if exists $opts{'t'} and $opts{'t'} =~ /^-?\d+$/; $reset_tail = $opts{'r'} if exists $opts{'r'} and $opts{'r'} =~ /^-?\d+$/; $prefix = 1 if exists $opts{'f'}; # read from STDIN if no args left chomp(@ARGV = ) unless @ARGV; # and flag the help text if nothing from STDIN help() unless @ARGV; for (@ARGV) { push @files, File::Tail->new( name => "$_", maxinterval => $maxinterval, interval => $interval, adjustafter => $adjustafter, tail => $tail, reset_tail => $reset_tail, ); } my $rin = ''; my $nfound; # don't buffer STDOUT $| = 1; while (1) { $nfound = File::Tail::select(undef, undef, undef, 60, @files); unless ($nfound) { my @ints; for (@files) { push @ints, $_->interval; } } for (@files) { unless ($_->predict) { print $_->{"input"}, ': ' if $prefix; print $_->read; } } } exit; ###################################################################### # # SUBROUTINES # a generic help blarb sub help { print <<"HELP"; Usage: $0 [opts] [file1 file2 .. fileN] Merges growing files into single stream Options for version $VERSION: -h/-? Display this message -f Prefix output with source filename (buggy) -m sec Check file for updates this often at most. -i sec Initial sleep period before checking file. -a sec Times to wait until adjusting check interval. -t num Read num lines from file. Negative is whole file. -r num Lines to read after file reset. Run perldoc(1) on this script for additional documentation. HELP exit; } ###################################################################### # # DOCUMENTATION =head1 NAME eet.pl - merges growing files into single stream =head1 SYNOPSIS To follow two log files at the same time: $ eet.pl /var/log/messages /var/log/maillog =head1 DESCRIPTION =head2 Overview This script does roughly the opposite of tee(1), reading in from multiple files and merging them all into STDOUT via L. =head2 Normal Usage $ eet.pl [options] [file1 file2 .. fileN] See L<"OPTIONS"> for details on the command line switches supported. If no files are mentioned on the command line for reading, this script will look fo them on STDIN. =head1 OPTIONS This script currently supports the following command line switches: =over 4 =item B<-h>, B<-?> Prints a brief usage note about the script. =item B<-f> Prefix output with source filenames. This only kinda worked during testing, and is probably due to how L behaves. =item B<-m> I (maxinterval) Check file for updates this often at most. =item B<-i> I (interval) Initial sleep period before checking file. =item B<-a> I (adjustafter) Times to wait until adjusting check interval. =item B<-t> I (tail) Read num lines from file. Negative is whole file. =item B<-r> I (reset_tail) Lines to read after file reset. =back See L for more information on the parenthesized parameter names, which are L parameters passed directy to the object. =head1 EXAMPLES Read through then follow several Apache VirtualHost logfiles, and send them off to colorize.pl: $ eet.pl -t -1 /www/site/logs/*_log | colorize.pl See http://colorize.raszi.hu/ for colorize.pl. =head1 BUGS =head2 Reporting Bugs Newer versions of this script may be available from: http://sial.org/code/perl/ If the bug is in the latest version, send a report to the author. Patches that fix problems or add new features are welcome. =head2 Known Issues The B<-f> prefix option does not work right all the time. =head1 SEE ALSO perl(1) =head1 AUTHOR Jeremy Mates, http://sial.org/contact/ =head1 COPYRIGHT Copyright (c) 2001-2002, Jeremy Mates. This script is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 HISTORY Based heavily on the select_demo script from L by Matija Grabnar. =head1 VERSION $Id: eet.pl,v 1.15 2003/01/13 05:28:42 jmates Exp $ =cut