1package File::Tail; 2 3use strict; 4use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $Is_Win32); 5 6$Is_Win32 = ($^O =~ /win32/i) ? 1 : 0; 7 8require Exporter; 9 10@ISA = qw(Exporter); 11# Items to export into callers namespace by default. Note: do not export 12# names by default without a very good reason. Use EXPORT_OK instead. 13# Do not simply export all your public functions/methods/constants. 14$VERSION = '1.3'; 15 16 17# Preloaded methods go here. 18 19use FileHandle; 20#use IO::Seekable; # does not define SEEK_SET in 5005.02 21use File::stat; 22use Carp; 23use Time::HiRes qw ( time sleep ); #import hires microsecond timers 24 25sub SEEK_SET () {0;} 26sub SEEK_CUR () {1;} 27sub SEEK_END () {2;} 28 29 30sub interval { 31 my $object=shift @_; 32 if (@_) { 33 $object->{interval}=shift; 34 $object->{interval}=$object->{maxinterval} if 35 $object->{interval}>$object->{maxinterval}; 36 } 37 $object->{interval}; 38} 39 40sub logit { 41 my $object=shift; 42 my @call=caller(1); 43 print # STDERR 44# time()." ". 45 "\033[7m". 46 $call[3]." ".$object->{"input"}." ".join("",@_). 47 "\033[0m". 48 "\n" 49 if $object->debug; 50} 51 52sub adjustafter { 53 my $self=shift; 54 $self->{adjustafter}=shift if @_; 55 return $self->{adjustafter}; 56} 57 58sub debug { 59 my $self=shift; 60 $self->{"debug"}=shift if @_; 61 return $self->{"debug"}; 62} 63 64sub errmode { 65 my($self, $mode) = @_; 66 my($prev) = $self->{errormode}; 67 68 if (@_ >= 2) { 69 ## Set the error mode. 70 defined $mode or $mode = ''; 71 if (ref($mode) eq 'CODE') { 72 $self->{errormode} = $mode; 73 } elsif (ref($mode) eq 'ARRAY') { 74 unless (ref($mode->[0]) eq 'CODE') { 75 croak 'bad errmode: first item in list must be a code ref'; 76 $mode = 'die'; 77 } 78 $self->{errormode} = $mode; 79 } else { 80 $self->{errormode} = lc $mode; 81 } 82 } 83 $prev; 84} 85 86sub errmsg { 87 my($self, @errmsgs) = @_; 88 my($prev) = $self->{errormsg}; 89 90 if (@_ > 0) { 91 $self->{errormsg} = join '', @errmsgs; 92 } 93 94 $prev; 95} # end sub errmsg 96 97 98sub error { 99 my($self, @errmsg) = @_; 100 my( 101 $errmsg, 102 $func, 103 $mode, 104 @args, 105 ); 106 107 if (@_ >= 1) { 108 ## Put error message in the object. 109 $errmsg = join '', @errmsg; 110 $self->{"errormsg"} = $errmsg; 111 112 ## Do the error action as described by error mode. 113 $mode = $self->{"errormode"}; 114 if (ref($mode) eq 'CODE') { 115 &$mode($errmsg); 116 return; 117 } elsif (ref($mode) eq 'ARRAY') { 118 ($func, @args) = @$mode; 119 &$func(@args); 120 return; 121 } elsif ($mode eq "return") { 122 return; 123 } elsif ($mode eq "warn") { 124 carp $errmsg; 125 } else { # die 126 croak $errmsg; 127 } 128 } else { 129 return $self->{"errormsg"} ne ''; 130 } 131} # end sub error 132 133 134sub copy { 135 my $self=shift; 136 $self->{copy}=shift if @_; 137 return $self->{copy}; 138} 139 140sub tail { 141 my $self=shift; 142 $self->{"tail"}=shift if @_; 143 return $self->{"tail"}; 144} 145 146sub reset_tail { 147 my $self=shift; 148 $self->{reset_tail}=shift if @_; 149 return $self->{reset_tail}; 150} 151 152sub nowait { 153 my $self=shift; 154 $self->{nowait}=shift if @_; 155 return $self->{nowait}; 156} 157 158sub method { 159 my $self=shift; 160 $self->{method}=shift if @_; 161 return $self->{method}; 162} 163 164sub input { 165 my $self=shift; 166 $self->{input}=shift if @_; 167 return $self->{input}; 168} 169 170sub maxinterval { 171 my $self=shift; 172 $self->{maxinterval}=shift if @_; 173 return $self->{maxinterval}; 174} 175 176sub resetafter { 177 my $self=shift; 178 $self->{resetafter}=shift if @_; 179 return $self->{resetafter}; 180} 181 182sub ignore_nonexistant { 183 my $self=shift; 184 $self->{ignore_nonexistant}=shift if @_; 185 return $self->{ignore_nonexistant}; 186} 187 188sub name_changes { 189 my $self=shift; 190 $self->{name_changes_callback}=shift if @_; 191 return $self->{name_changes_callback}; 192} 193 194sub TIEHANDLE { 195 my $ref=new(@_); 196} 197 198sub READLINE { 199 $_[0]->read(); 200} 201 202sub PRINT { 203 $_[0]->error("PRINT makes no sense in File::Tail"); 204} 205 206sub PRINTF { 207 $_[0]->error("PRINTF makes no sense in File::Tail"); 208} 209 210sub READ { 211 $_[0]->error("READ not implemented in File::Tail -- use READLINE (<HANDLE>) instead"); 212} 213 214sub GETC { 215 $_[0]->error("GETC not (yet) implemented in File::Tail -- use READLINE (<HANDLE>) instead"); 216} 217 218sub DESTROY { 219 my($this) = $_[0]; 220 close($this->{"handle"}) if (defined($this) && defined($this->{'handle'})); 221# undef $_[0]; 222 return; 223} 224 225sub CLOSE { 226 &DESTROY(@_); 227} 228 229sub new { 230 my ($pkg)=shift @_; 231 $pkg=ref($pkg) || $pkg; 232 unless ($pkg) { 233 $pkg="File::Tail"; 234 } 235 my %params; 236 if ($#_ == 0) { 237 $params{"name"}=$_[0]; 238 } else { 239 if (($#_ % 2) != 1) { 240 croak "Odd number of parameters for new"; 241 return; 242 } 243 %params=@_; 244 } 245 my $object = {}; 246 bless $object,$pkg; 247 unless (defined($params{'name'})) { 248 croak "No file name given. Pass filename as \"name\" parameter"; 249 return; 250 } 251 $object->input($params{'name'}); 252 $object->copy($params{'cname'}); 253 $object->method($params{'method'} || "tail"); 254 $object->{buffer}=""; 255 $object->maxinterval($params{'maxinterval'} || 60); 256 $object->interval($params{'interval'} || 10); 257 $object->adjustafter($params{'adjustafter'} || 10); 258 $object->errmode($params{'errmode'} || "die"); 259 $object->resetafter($params{'resetafter'} || 260 ($object->maxinterval*$object->adjustafter)); 261 $object->{"debug"}=($params{'debug'} || 0); 262 $object->{"tail"}=($params{'tail'} || 0); 263 $object->{"nowait"}=($params{'nowait'} || 0); 264 $object->{"maxbuf"}=($params{'maxbuf'} || 16384); 265 warn "maxbuf should be big enough to hold at least one longest probable line, and preferably several\n" 266 unless $object->{"maxbuf"}>1024; 267 $object->{"name_changes_callback"}=($params{'name_changes'} || undef); 268 if (defined $params{'reset_tail'}) { 269 $object->{"reset_tail"} = $params{'reset_tail'}; 270 } else { 271 $object->{"reset_tail"} = -1; 272 } 273 $object->{'ignore_nonexistant'}=($params{'ignore_nonexistant'} || 0); 274 $object->{"lastread"}=0; 275 $object->{"sleepcount"}=0; 276 $object->{"lastcheck"}=0; 277 $object->{"lastreset"}=0; 278 $object->{"nextcheck"}=time(); 279 if ($object->{"method"} eq "tail") { 280 $object->reset_pointers; 281 } 282# $object->{curpos}=0; # ADDED 25May01: undef warnings when 283# $object->{endpos}=0; # starting up on a nonexistant file 284 return $object; 285} 286 287# Sets position in file when first opened or after that when reset: 288# Sets {endpos} and {curpos} for current {handle} based on {tail}. 289# Sets {tail} to value of {reset_tail}; effect is that first call 290# uses {tail} and subsequent calls use {reset_tail}. 291sub position { 292 my $object=shift; 293 $object->{"endpos"}=sysseek($object->{handle},0,SEEK_END); 294 unless ($object->{"tail"}) { 295 $object->{endpos}=$object->{curpos}= 296 sysseek($object->{handle},0,SEEK_END); 297 } elsif ($object->{"tail"}<0) { 298 $object->{endpos}=sysseek($object->{handle},0,SEEK_END); 299 $object->{curpos}=sysseek($object->{handle},0,SEEK_SET); 300 } else { 301 my $crs=0; 302 my $maxlen=sysseek($object->{handle},0,SEEK_END); 303 while ($crs<$object->{"tail"}+1) { 304 my $avlen=length($object->{"buffer"})/($crs+1); 305 $avlen=80 unless $avlen; 306 my $calclen=$avlen*$object->{"tail"}; 307 $calclen=length($object->{buffer})+1024 if int($calclen)<=length($object->{"buffer"}); 308 $calclen=$maxlen if $calclen>$maxlen; 309 $object->{curpos}=sysseek($object->{handle},-$calclen,SEEK_END); 310 sysread($object->{handle},$object->{"buffer"}, 311 $calclen); 312 $object->{"buffer"} =~ s/\015\012/\n/g if $Is_Win32; 313 $object->{curpos}=sysseek($object->{handle},0,SEEK_CUR); 314 $crs=$object->{"buffer"}=~tr/\n//; 315 last if ($calclen>=$maxlen); 316 } 317 $object->{curpos}=sysseek($object->{handle},0,SEEK_CUR); 318 $object->{endpos}=sysseek($object->{handle},0,SEEK_END); 319 if ($crs>$object->{"tail"}) { 320 my $toskip=$crs-$object->{"tail"}; 321 my $pos; 322 $pos=index($object->{"buffer"},"\n"); 323 while (--$toskip) { 324 $pos=index($object->{"buffer"},"\n",$pos+1); 325 } 326 $object->{"buffer"}=substr($object->{"buffer"},$pos+1); 327 } 328 } 329 $object->{"tail"}=$object->{"reset_tail"}; 330} 331 332# Tries to open or reopen the file; failure is an error unless 333# {ignore_nonexistant} is set. 334# 335# For a new file (ie, first time opened) just does some book-keeping 336# and calls position for initial position setup. Otherwise does some 337# checks whether file has been replaced, and if so changes to the new 338# file. (Calls position for reset setup). 339# 340# Always updates {lastreset} to current time. 341# 342sub reset_pointers { 343 my $object=shift @_; 344 $object->{lastreset} = time(); 345 346 my $st; 347 348 my $oldhandle=$object->{handle}; 349 my $newhandle=FileHandle->new; 350 351 my $newname; 352 if ($oldhandle && $$object{'name_changes_callback'}) { 353 $newname=$$object{'name_changes_callback'}(); 354 $object->{"input"}= $newname; 355 } else { 356 $newname=$object->input; 357 } 358 359 unless (open($newhandle,"<$newname")) { 360 if ($object->{'ignore_nonexistant'}) { 361 # If we have an oldhandle, leave endpos and curpos to what they 362 # were, since oldhandle will still be the "current" handle elsewhere, 363 # eg, checkpending. This also allows tailing a file which is removed 364 # but still being written to. 365 if (!$oldhandle) { 366 $object->{'endpos'}=0; 367 $object->{'curpos'}=0; 368 } 369 return; 370 } 371 $object->error("Error opening ".$object->input.": $!"); 372 $object->{'endpos'}=0 unless defined($object->{'endpos'}); 373 $object->{'curpos'}=0 unless defined($object->{'curpos'}); 374 return; 375 } 376 binmode($newhandle); 377 378 if (defined($oldhandle)) { 379 # If file has not been changed since last OK read do not do anything 380 $st=stat($newhandle); 381 # lastread uses fractional time, stat doesn't. This can cause false 382 # negatives. 383 # If the file was changed the same second as it was last read, 384 # we only reopen it if it's length has changed. The alternative is that 385 # sometimes, files would be reopened needlessly, and with reset_tail 386 # set to -1, we would see the whole file again. 387 # Of course, if the file was removed the same second as when it was 388 # last read, and replaced (within that second) with a file of equal 389 # length, we're out of luck. I don't see how to fix this. 390 if ($st->mtime<=int($object->{'lastread'})) { 391 if (($st->size==$object->{"curpos"}) && ($st->ino == $object->{"inode"})) { 392 $object->{lastread} = $st->mtime; 393 return; 394 } else { 395 # will continue further to reset 396 } 397 } else { 398 } 399 $object->{handle}=$newhandle; 400 $object->{inode} = $st->ino; 401 $object->position; 402 $object->{lastread} = $st->mtime; 403 close($oldhandle); 404 } else { # This is the first time we are opening this file 405 $st=stat($newhandle); 406 $object->{handle}=$newhandle; 407 $object->position; 408 $object->{lastread}=$st->mtime; # for better estimate on initial read 409 } 410 411} 412 413 414sub checkpending { 415 my $object=shift @_; 416 417 my $old_lastcheck = $object->{lastcheck}; 418 $object->{"lastcheck"}=time; 419 unless ($object->{handle}) { 420 $object->reset_pointers; 421 unless ($object->{handle}) { # This try did not open the file either 422 return 0; 423 } 424 } 425 426 $object->{"endpos"}=sysseek($object->{handle},0,SEEK_END); 427 if ($object->{"endpos"}<$object->{curpos}) { # file was truncated 428 $object->position; 429 } elsif (($object->{curpos}==$object->{"endpos"}) 430 && (time()-$object->{lastread})>$object->{'resetafter'}) { 431 $object->reset_pointers; 432 $object->{"endpos"}=sysseek($object->{handle},0,SEEK_END); 433 } 434 435 if ($object->{"endpos"}-$object->{curpos}) { 436 sysseek($object->{handle},$object->{curpos},SEEK_SET); 437 readin($object,$object->{"endpos"}-$object->{curpos}); 438 } 439 return ($object->{"endpos"}-$object->{curpos}); 440} 441 442sub predict { 443 my $object=shift; 444 my $crs=$object->{"buffer"}=~tr/\n//; # Count newlines in buffer 445 my @call=caller(1); 446 return 0 if $crs; 447 my $ttw=$object->{"nextcheck"}-time(); 448 return $ttw if $ttw>0; 449 if (my $len=$object->checkpending) { 450 readin($object,$len); 451 return 0; 452 } 453 if ($object->{"sleepcount"}>$object->adjustafter) { 454 $object->{"sleepcount"}=0; 455 $object->interval($object->interval*10); 456 } 457 $object->{"sleepcount"}++; 458 $object->{"nextcheck"}=time()+$object->interval; 459 return ($object->interval); 460} 461 462sub bitprint { 463 return "undef" unless defined($_[0]); 464 return unpack("b*",$_[0]); 465} 466 467sub select { 468 my $object=shift @_ if ref($_[0]); 469 my ($timeout,@fds)=splice(@_,3); 470 $object=$fds[0] unless defined($object); 471 my ($savein,$saveout,$saveerr)=@_; 472 my ($minpred,$mustreturn); 473 if (defined($timeout)) { 474 $minpred=$timeout; 475 $mustreturn=time()+$timeout; 476 } else { 477 $minpred=$fds[0]->predict; 478 } 479 foreach (@fds) { 480 my $val=$_->predict; 481 $minpred=$val if $minpred>$val; 482 } 483 my ($nfound,$timeleft); 484 my @retarr; 485 while (defined($timeout)?(!$nfound && (time()<$mustreturn)):!$nfound) { 486# Restore bitmaps in case we called select before 487 splice(@_,0,3,$savein,$saveout,$saveerr); 488 489 490 ($nfound,$timeleft)=select($_[0],$_[1],$_[2],$minpred); 491 492 493 if (defined($timeout)) { 494 $minpred=$timeout; 495 } else { 496 $minpred=$fds[0]->predict; 497 } 498 undef @retarr; 499 foreach (@fds) { 500 my $val=$_->predict; 501 $nfound++ unless $val; 502 $minpred=$val if $minpred>$val; 503 push(@retarr,$_) unless $val; 504 } 505 } 506 if (wantarray) { 507 return ($nfound,$timeleft,@retarr); 508 } else { 509 return $nfound; 510 } 511} 512 513sub readin { 514 my $crs; 515 my ($object,$len)=@_; 516 if (length($object->{"buffer"})) { 517 # this means the file was reset AND a tail -n was active 518 $crs=$object->{"buffer"}=~tr/\n//; # Count newlines in buffer 519 return $crs if $crs; 520 } 521 $len=$object->{"maxbuf"} if ($len>$object->{"maxbuf"}); 522 my $nlen=$len; 523 while ($nlen>0) { 524 $len=sysread($object->{handle},$object->{"buffer"}, 525 $nlen,length($object->{"buffer"})); 526 $object->{"buffer"} =~ s/\015\012/\n/g if $Is_Win32; 527 528 last if $len==0; # Some busy filesystems return 0 sometimes, 529 # and never give anything more from then on if 530 # you don't give them time to rest. This return 531 # allows File::Tail to use the usual exponential 532 # backoff. 533 $nlen=$nlen-$len; 534 } 535 $object->{curpos}=sysseek($object->{handle},0,SEEK_CUR); 536 537 $crs=$object->{"buffer"}=~tr/\n//; 538 539 if ($crs) { 540 my $tmp=time; 541 $object->{lastread}=$tmp if $object->{lastread}>$tmp; #??? 542 $object->interval(($tmp-($object->{lastread}))/$crs); 543 $object->{lastread}=$tmp; 544 } 545 return ($crs); 546} 547 548sub read { 549 my $object=shift @_; 550 my $len; 551 my $pending=$object->{"endpos"}-$object->{"curpos"}; 552 my $crs=$object->{"buffer"}=~m/\n/; 553 while (!$pending && !$crs) { 554 $object->{"sleepcount"}=0; 555 while ($object->predict) { 556 if ($object->nowait) { 557 if (wantarray) { 558 return (); 559 } else { 560 return ""; 561 } 562 } 563 sleep($object->interval) if ($object->interval>0); 564 } 565 $pending=$object->{"endpos"}-$object->{"curpos"}; 566 $crs=$object->{"buffer"}=~m/\n/; 567 } 568 569 if (!length($object->{"buffer"}) || index($object->{"buffer"},"\n")<0) { 570 readin($object,$pending); 571 } 572 unless (wantarray) { 573 my $str=substr($object->{"buffer"},0, 574 1+index($object->{"buffer"},"\n")); 575 $object->{"buffer"}=substr($object->{"buffer"}, 576 1+index($object->{"buffer"},"\n")); 577 return $str; 578 } else { 579 my @str; 580 while (index($object->{"buffer"},"\n")>-1) { 581 push(@str,substr($object->{"buffer"},0, 582 1+index($object->{"buffer"},"\n"))); 583 $object->{"buffer"}=substr($object->{"buffer"}, 584 1+index($object->{"buffer"},"\n")); 585 586 } 587 return @str; 588 } 589} 590 5911; 592 593__END__ 594 595=head1 NAME 596 597File::Tail - Perl extension for reading from continously updated files 598 599=head1 SYNOPSIS 600 601 use File::Tail; 602 $file=File::Tail->new("/some/log/file"); 603 while (defined($line=$file->read)) { 604 print "$line"; 605 } 606 607 use File::Tail; 608 $file=File::Tail->new(name=>$name, maxinterval=>300, adjustafter=>7); 609 while (defined($line=$file->read)) { 610 print "$line"; 611 } 612 613OR, you could use tie (additional parameters can be passed with the name, or 614can be set using $ref): 615 616 use File::Tail; 617 my $ref=tie *FH,"File::Tail",(name=>$name); 618 while (<FH>) { 619 print "$_"; 620 } 621 622 623Note that the above script will never exit. If there is nothing being written 624to the file, it will simply block. 625 626You can find more synopsii in the file logwatch, which is included 627in the distribution. 628 629Note: Select functionality was added in version 0.9, and it required 630some reworking of all routines. ***PLEASE*** let me know if you see anything 631strange happening. 632 633You can find two way of using select in the file select_demo which is included 634in the ditribution. 635 636=head1 DESCRIPTION 637 638The primary purpose of File::Tail is reading and analysing log files while 639they are being written, which is especialy usefull if you are monitoring 640the logging process with a tool like Tobias Oetiker's MRTG. 641 642The module tries very hard NOT to "busy-wait" on a file that has little 643traffic. Any time it reads new data from the file, it counts the number 644of new lines, and divides that number by the time that passed since data 645were last written to the file before that. That is considered the average 646time before new data will be written. When there is no new data to read, 647C<File::Tail> sleeps for that number of seconds. Thereafter, the waiting 648time is recomputed dynamicaly. Note that C<File::Tail> never sleeps for 649more than the number of seconds set by C<maxinterval>. 650 651If the file does not get altered for a while, C<File::Tail> gets suspicious 652and startschecking if the file was truncated, or moved and recreated. If 653anything like that had happened, C<File::Tail> will quietly reopen the file, 654and continue reading. The only way to affect what happens on reopen is by 655setting the reset_tail parameter (see below). The effect of this is that 656the scripts need not be aware when the logfiles were rotated, they will 657just quietly work on. 658 659Note that the sleep and time used are from Time::HiRes, so this module 660should do the right thing even if the time to sleep is less than one second. 661 662The logwatch script (also included) demonstrates several ways of calling 663the methods. 664 665=head1 CONSTRUCTOR 666 667=head2 new ([ ARGS ]) 668 669Creates a C<File::Tail>. If it has only one paramter, it is assumed to 670be the filename. If the open fails, the module performs a croak. I 671am currently looking for a way to set $! and return undef. 672 673You can pass several parameters to new: 674 675=over 4 676 677=item name 678 679This is the name of the file to open. The file will be opened for reading. 680This must be a regular file, not a pipe or a terminal (i.e. it must be 681seekable). 682 683=item maxinterval 684 685The maximum number of seconds (real number) that will be spent sleeping. 686Default is 60, meaning C<File::Tail> will never spend more than sixty 687seconds without checking the file. 688 689=item interval 690 691The initial number of seconds (real number) that will be spent sleeping, 692before the file is first checked. Default is ten seconds, meaning C<File::Tail> 693will sleep for 10 seconds and then determine, how many new lines have appeared 694in the file. 695 696=item adjustafter 697 698The number of C<times> C<File::Tail> waits for the current interval, 699before adjusting the interval upwards. The default is 10. 700 701=item resetafter 702 703The number of seconds after last change when C<File::Tail> decides 704the file may have been closed and reopened. The default is 705adjustafter*maxinterval. 706 707=item maxbuf 708 709The maximum size of the internal buffer. When File::Tail 710suddenly found an enormous ammount of information in the file 711(for instance if the retry parameters were set to very 712infrequent checking and the file was rotated), File::Tail 713sometimes slurped way too much file into memory. This sets 714the maximum size of File::Tail's buffer. 715 716Default value is 16384 (bytes). 717 718A large internal buffer may result in worse performance (as well as 719increased memory usage), since File::Tail will have to do more work 720processing the internal buffer. 721 722=item nowait 723 724Does not block on read, but returns an empty string if there is nothing 725to read. DO NOT USE THIS unless you know what you are doing. If you 726are using it in a loop, you probably DON'T know what you are doing. 727If you want to read tails from multiple files, use select. 728 729 730=item ignore_nonexistant 731 732 Do not complain if the file doesn't exist when it is first 733opened or when it is to be reopened. (File may be reopened after 734resetafter seconds have passed since last data was found.) 735 736=item tail 737 738 When first started, read and return C<n> lines from the file. 739If C<n> is zero, start at the end of file. If C<n> is negative, 740return the whole file. 741 742 Default is C<0>. 743 744=item reset_tail 745 746 Same as tail, but applies after reset. (i.e. after the 747file has been automaticaly closed and reopened). Defaults to 748C<-1>, i.e. does not skip any information present in the 749file when it first checks it. 750 751 Why would you want it otherwise? I've seen files which 752have been cycled like this: 753 754 grep -v lastmonth log >newlog 755 mv log archive/lastmonth 756 mv newlog log 757 kill -HUP logger 758 759 760Obviously, if this happens and you have reset_tail set to 761c<-1>, you will suddenly get a whole bunch of lines - lines 762you already saw. So in this case, reset_tail should probably 763be set to a small positive number or even C<0>. 764 765=item name_changes 766 767Some logging systems change the name of the file 768they are writing to, sometimes to include a date, sometimes a 769sequence number, sometimes other, even more bizarre changes. 770 771Instead of trying to implement various clever detection methods, 772File::Tail will call the code reference defined in name_changes. The code reference should return the string which is the new name of the file to try opening. 773 774Note that if the file does not exist, File::Tail will report a fatal error (unless ignore_nonexistant has also been specified). 775 776=item debug 777 778Set to nonzero if you want to see more about the inner workings of 779File::Tail. Otherwise not useful. 780 781=item errmode 782 783Modeled after the methods from Net:Telnet, here you decide how the 784errors should be handled. The parameter can be a code reference which 785is called with the error string as a parameter, an array with a code 786reference as the first parameter and other parameters to be passed to 787handler subroutine, or one of the words: 788 789return - ignore any error (just put error message in errmsg). 790warn - output the error message but continue 791die - display error message and exit 792 793Default is die. 794 795=back 796 797=head1 METHODS 798 799=head2 read 800 801C<read> returns one line from the input file. If there are no lines 802ready, it blocks until there are. 803 804=head2 select 805 806C<select> is intended to enable the programmer to simoultaneously wait for 807input on normal filehandles and File::Tail filehandles. Of course, you may 808use it to simply read from more than one File::Tail filehandle at a time. 809 810 811Basicaly, you call File::Tail::select just as you would normal select, 812with fields for rbits, wbits and ebits, as well as a timeout, however, you 813can tack any number of File::Tail objects (not File::Tail filehandles!) 814to the end. 815 816Usage example: 817 818 foreach (@ARGV) { 819 push(@files,File::Tail->new(name=>"$_",debug=>$debug)); 820 } 821 while (1) { 822 ($nfound,$timeleft,@pending)= 823 File::Tail::select(undef,undef,undef,$timeout,@files); 824 unless ($nfound) { 825 # timeout - do something else here, if you need to 826 } else { 827 foreach (@pending) { 828 print $_->{"input"}." (".localtime(time).") ".$_->read; 829 } 830 } 831 832 # 833 # There is a more elaborate example in select_demo in the distribution. 834 # 835 836When you do this, File::Tail's select emulates normal select, with two 837exceptions: 838 839a) it will return if there is input on any of the parameters 840(i.e. normal filehandles) _or_ File::Tails. 841 842b) In addition to C<($nfound, $timeleft)>, the return array will also contain 843a list of File::Tail objects which are ready for reading. C<$nfound> will 844contain the correct number of filehandles to be read (i.e. both normal 845and File::Tails). 846 847Once select returns, when you want to determine which File::Tail objects 848have input ready, you can either use the list of objects select returned, 849or you can check each individual object with $object->predict. This returns 850the ammount of time (in fractional seconds) after which the handle expects 851input. If it returns 0, there is input waiting. There is no guarantee that 852there will be input waiting after the returned number of seconds has passed. 853However, File::Tail won't do any I/O on the file until that time has passed. 854Note that the value of $timeleft may or may not be correct - that depends on 855the underlying operating system (and it's select), so you're better off NOT 856relying on it. 857 858Also note, if you are determining which files are ready for input by calling 859each individual predict, the C<$nfound> value may be invalid, because one 860or more of File::Tail object may have become ready between the time select 861has returned and the time when you checked it. 862 863=head1 TO BE DONE 864 865Planned for 1.0: Using $/ instead of \n to 866separate "lines" (which should make it possible to read wtmp type files). 867Except that I discovered I have no need for that enhancement If you do, 868feel free to send me the patches and I'll apply them - if I feel they don't 869add too much processing time. 870 871=head1 AUTHOR 872 873Matija Grabnar, matija.grabnar@arnes.si 874 875=head1 SEE ALSO 876 877perl(1), tail (1), 878MRTG (http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html) 879 880=cut 881 882